You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdesvn/src/svnfrontend/tdesvnfilelist.cpp

3161 lines
99 KiB

/***************************************************************************
* Copyright (C) 2005-2007 by Rajko Albrecht *
* ral@alwins-world.de *
* *
* 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. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "tdesvnfilelist.h"
#include "tdesvn_part.h"
#include "filelistviewitem.h"
#include "importdir_logmsg.h"
#include "copymoveview_impl.h"
#include "mergedlg_impl.h"
#include "svnactions.h"
#include "svnfiletip.h"
#include "keystatus.h"
#include "opencontextmenu.h"
#include "checkoutinfo_impl.h"
#include "stopdlg.h"
#include "tdesvnsettings.h"
#include "revision.hpp"
#include "dirent.hpp"
#include "client.hpp"
#include "status.hpp"
#include "url.hpp"
#include "sshagent.h"
#include "sub2qt.h"
#include "cursorstack.h"
#include "widgetblockstack.h"
#include <kapplication.h>
#include <kiconloader.h>
#include <kdirwatch.h>
#include <klocale.h>
#include <kactioncollection.h>
#include <kshortcut.h>
#include <kmessagebox.h>
#include <kdirselectdialog.h>
#include <klineedit.h>
#include <kfileitem.h>
#include <kdialog.h>
#include <kfiledialog.h>
#include <kdebug.h>
#include <kurldrag.h>
#include <ktempfile.h>
#include <kio/job.h>
#include <krun.h>
#include <kurldrag.h>
#include <ktrader.h>
#include <tqvbox.h>
#include <tqpainter.h>
#include <tqstyle.h>
#include <tqapplication.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqtooltip.h>
#include <tqregexp.h>
#include <tqpopupmenu.h>
#include <tqcursor.h>
#include <tqheader.h>
#include <tqcheckbox.h>
#include <unistd.h>
class KdesvnFileListPrivate{
public:
KdesvnFileListPrivate();
virtual ~KdesvnFileListPrivate()
{
if (m_DirWatch) {
m_DirWatch->stopScan();
delete m_DirWatch;
}
delete m_fileTip;
kdDebug()<<"Destructor KdesvnFileListPrivate done"<<endl;
};
TQListViewItem *dragOverItem;
TQPoint dragOverPoint;
TQRect mOldDropHighlighter;
svn::Revision m_remoteRevision;
KDirWatch*m_DirWatch;
SvnFileTip*m_fileTip;
int mlist_icon_size;
bool mdisp_ignored_files;
bool mdisp_unknown_files;
bool mdisp_overlay;
/* returns true if the display must refreshed */
bool reReadSettings();
bool intern_dropRunning;
KURL::List intern_drops;
TQString intern_drop_target,merge_Src1, merge_Src2,merge_Target;
TQDropEvent::Action intern_drop_action;
TQPoint intern_drop_pos;
TQTimer drop_timer;
TQTimer dirwatch_timer;
TQTimer propTimer;
bool mousePressed;
TQPoint presspos;
TQMap<TQString,TQChar> dirItems;
void stopDirTimer()
{
dirwatch_timer.stop();
}
void startDirTimer()
{
dirwatch_timer.start(250,true);
}
void connectDirTimer(TQObject*ob)
{
TQObject::connect(&dirwatch_timer,TQT_SIGNAL(timeout()),ob,TQT_SLOT(_dirwatchTimeout()));
}
void stopScan()
{
if (m_DirWatch) {
m_DirWatch->stopScan();
}
}
void startScan()
{
if (m_DirWatch) {
m_DirWatch->startScan();
}
}
void startProptimer()
{
propTimer.start(100,true);
}
void stopProptimer()
{
propTimer.stop();
}
void connectPropTimer(TQObject*ob)
{
TQObject::connect(&propTimer,TQT_SIGNAL(timeout()),ob,TQT_SLOT(_propListTimeout()));
}
private:
void readSettings();
};
KdesvnFileListPrivate::KdesvnFileListPrivate()
: dragOverItem(0),dragOverPoint(TQPoint(0,0)),mOldDropHighlighter()
{
m_remoteRevision = svn::Revision::HEAD;
m_DirWatch = 0;
intern_dropRunning=false;
mousePressed = false;
readSettings();
}
void KdesvnFileListPrivate::readSettings()
{
mlist_icon_size = Kdesvnsettings::listview_icon_size();
mdisp_ignored_files = Kdesvnsettings::display_ignored_files();
mdisp_unknown_files = Kdesvnsettings::display_unknown_files();
mdisp_overlay = Kdesvnsettings::display_overlays();
}
bool KdesvnFileListPrivate::reReadSettings()
{
int _size = mlist_icon_size;
bool _ignored = mdisp_ignored_files;
bool _overlay = mdisp_overlay;
bool _unknown = mdisp_unknown_files;
readSettings();
return (_size != mlist_icon_size||
_ignored!=mdisp_ignored_files||
_overlay!=mdisp_overlay||
_unknown != mdisp_unknown_files);
}
tdesvnfilelist::tdesvnfilelist(KActionCollection*aCollect,TQWidget *parent, const char *name)
: KListView(parent, name),ItemDisplay(),m_SvnWrapper(new SvnActions(this))
{
m_SelectedItems = 0;
m_pList = new KdesvnFileListPrivate;
m_filesAction = aCollect;
m_pList->m_fileTip=new SvnFileTip(this);
m_pList->m_fileTip->setOptions(Kdesvnsettings::display_file_tips()&&
TQToolTip::isGloballyEnabled(),true,6);
SshAgent ssh;
ssh.querySshAgent();
setMultiSelection(true);
setSelectionModeExt(FileManager);
setShowSortIndicator(true);
setAllColumnsShowFocus (true);
setRootIsDecorated(true);
addColumn(i18n("Name"));
addColumn(i18n("Status"));
addColumn(i18n("Last changed Revision"));
addColumn(i18n("Last author"));
addColumn(i18n("Last change date"));
addColumn(i18n("Locked by"));
setSortColumn(FileListViewItem::COL_NAME);
setupActions();
connect(this,TQT_SIGNAL(contextMenuRequested(TQListViewItem *, const TQPoint &, int)),this,
TQT_SLOT(slotContextMenuRequested(TQListViewItem *, const TQPoint &, int)));
/* not via executed 'cause click may used for selection - single click execution
just confuses in an application */
connect(this,TQT_SIGNAL(doubleClicked(TQListViewItem*)),this,TQT_SLOT(slotItemDoubleClicked(TQListViewItem*)));
connect(this,TQT_SIGNAL(returnPressed(TQListViewItem*)),this,TQT_SLOT(slotItemDoubleClicked(TQListViewItem*)));
connect(this,TQT_SIGNAL(selectionChanged()),this,TQT_SLOT(slotSelectionChanged()));
connect(m_SvnWrapper,TQT_SIGNAL(clientException(const TQString&)),this,TQT_SLOT(slotClientException(const TQString&)));
connect(m_SvnWrapper,TQT_SIGNAL(sendNotify(const TQString&)),this,TQT_SLOT(slotNotifyMessage(const TQString&)));
connect(m_SvnWrapper,TQT_SIGNAL(reinitItem(SvnItem*)),this,TQT_SLOT(slotReinitItem(SvnItem*)));
connect(m_SvnWrapper,TQT_SIGNAL(sigRefreshAll()),this,TQT_SLOT(refreshCurrentTree()));
connect(m_SvnWrapper,TQT_SIGNAL(sigRefreshCurrent(SvnItem*)),this,TQT_SLOT(refreshCurrent(SvnItem*)));
connect(m_SvnWrapper,TQT_SIGNAL(sigRefreshIcons(bool)),this,TQT_SLOT(slotRescanIcons(bool)));
connect(this,TQT_SIGNAL(dropped (TQDropEvent*,TQListViewItem*)),
this,TQT_SLOT(slotDropped(TQDropEvent*,TQListViewItem*)));
connect(m_SvnWrapper,TQT_SIGNAL(sigGotourl(const TQString&)),this,TQT_SLOT(_openURL(const TQString&)));
connect(m_SvnWrapper,TQT_SIGNAL(sigCacheStatus(TQ_LONG,TQ_LONG)),this,TQT_SIGNAL(sigCacheStatus(TQ_LONG,TQ_LONG)));
connect(m_SvnWrapper,TQT_SIGNAL(sigThreadsChanged()),this,TQT_SLOT(enableActions()));
m_pList->connectDirTimer(TQT_TQOBJECT(this));
m_pList->connectPropTimer(TQT_TQOBJECT(this));
setDropHighlighter(true);
setDragEnabled(true);
setItemsMovable(true);
setDropVisualizer(false);
setAcceptDrops(true);
}
svn::Client*tdesvnfilelist::svnclient()
{
return m_SvnWrapper->svnclient();
}
void tdesvnfilelist::setupActions()
{
if (!m_filesAction) return;
KAction*tmp_action;
/* local and remote actions */
/* 1. actions on dirs AND files */
//new KAction(i18n("Log..."),"tdesvnlog",KShortcut(SHIFT+CTRL+Key_L),this,TQT_SLOT(slotMakeRangeLog()),m_filesAction,"make_svn_log");
new KAction(i18n("Full Log"),"tdesvnlog",KShortcut(CTRL+Key_L),TQT_TQOBJECT(this),TQT_SLOT(slotMakeLog()),m_filesAction,"make_svn_log_full");
new KAction(i18n("Full revision tree"),"tdesvnlog",KShortcut(CTRL+Key_T),TQT_TQOBJECT(this),TQT_SLOT(slotMakeTree()),m_filesAction,"make_svn_tree");
new KAction(i18n("Partial revision tree"),"tdesvnlog",KShortcut(SHIFT+CTRL+Key_T),
TQT_TQOBJECT(this),TQT_SLOT(slotMakePartTree()),m_filesAction,"make_svn_partialtree");
new KAction(i18n("Properties"),"edit",
KShortcut(CTRL+Key_P),m_SvnWrapper,TQT_SLOT(slotProperties()),m_filesAction,"make_svn_property");
new KAction(i18n("Display Properties"),"edit",
KShortcut(SHIFT+CTRL+Key_P),TQT_TQOBJECT(this),TQT_SLOT(slotDisplayProperties()),m_filesAction,"get_svn_property");
tmp_action = new KAction(i18n("Display last changes"),"tdesvndiff",
KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotDisplayLastDiff()),m_filesAction,"make_last_change");
tmp_action->setToolTip(i18n("Display last changes as difference to previous commit."));
m_InfoAction = new KAction(i18n("Details"),"tdesvninfo",
KShortcut(CTRL+Key_I),TQT_TQOBJECT(this),TQT_SLOT(slotInfo()),m_filesAction,"make_svn_info");
m_RenameAction = new KAction(i18n("Move"),"move",
KShortcut(Key_F2),TQT_TQOBJECT(this),TQT_SLOT(slotRename()),m_filesAction,"make_svn_rename");
m_CopyAction = new KAction(i18n("Copy"),"tdesvncopy",
KShortcut(CTRL+Key_C),TQT_TQOBJECT(this),TQT_SLOT(slotCopy()),m_filesAction,"make_svn_copy");
tmp_action = new KAction(i18n("Check for updates"),"tdesvncheckupdates",KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotCheckUpdates()),m_filesAction,"make_check_updates");
tmp_action->setToolTip(i18n("Check if current working copy has items with newer version in repository"));
/* 2. actions only on files */
m_BlameAction = new KAction(i18n("Blame"),"tdesvnblame",
KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotBlame()),m_filesAction,"make_svn_blame");
m_BlameAction->setToolTip(i18n("Output the content of specified files or URLs with revision and author information in-line."));
m_BlameRangeAction = new KAction(i18n("Blame range"),"tdesvnblame",
KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotRangeBlame()),m_filesAction,"make_svn_range_blame");
m_BlameRangeAction->setToolTip(i18n("Output the content of specified files or URLs with revision and author information in-line."));
m_CatAction = new KAction(i18n("Cat head"), "tdesvncat",
KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotCat()),m_filesAction,"make_svn_cat");
m_CatAction->setToolTip(i18n("Output the content of specified files or URLs."));
tmp_action = new KAction(i18n("Cat revision..."),"tdesvncat",
KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotRevisionCat()),m_filesAction,"make_revisions_cat");
tmp_action->setToolTip(i18n("Output the content of specified files or URLs at specific revision."));
m_LockAction = new KAction(i18n("Lock current items"),"tdesvnlock",
KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotLock()),m_filesAction,"make_svn_lock");
m_UnlockAction = new KAction(i18n("Unlock current items"),"tdesvnunlock",
KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotUnlock()),m_filesAction,"make_svn_unlock");
/* 3. actions only on dirs */
m_MkdirAction = new KAction(i18n("New folder"),"folder_new",
KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotMkdir()),m_filesAction,"make_svn_mkdir");
m_switchRepository = new KAction(i18n("Switch repository"),"tdesvnswitch",
KShortcut(), m_SvnWrapper,TQT_SLOT(slotSwitch()),m_filesAction,"make_svn_switch");
m_switchRepository->setToolTip(i18n("Switch repository path of current working copy path (\"svn switch\")"));
tmp_action = new KAction(i18n("Relocate current working copy url"),"tdesvnrelocate",KShortcut(),
TQT_TQOBJECT(this),TQT_SLOT(slotRelocate()),m_filesAction,"make_svn_relocate");
tmp_action->setToolTip(i18n("Relocate url of current working copy path to other url"));
tmp_action = new KAction(i18n("Check for unversioned items"),"tdesvnaddrecursive",KShortcut(),
TQT_TQOBJECT(this),TQT_SLOT(slotCheckNewItems()),m_filesAction,"make_check_unversioned");
tmp_action->setToolTip(i18n("Browse folder for unversioned items and add them if wanted."));
m_changeToRepository = new KAction(i18n("Open repository of working copy"),"gohome",KShortcut(),
TQT_TQOBJECT(this),TQT_SLOT(slotChangeToRepository()),m_filesAction,"make_switch_to_repo");
m_changeToRepository->setToolTip(i18n("Opens the repository the current working copy was checked out from"));
m_CleanupAction = new KAction(i18n("Cleanup"),"tdesvncleanup",
KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotCleanupAction()),m_filesAction,"make_cleanup");
m_CleanupAction->setToolTip(i18n("Recursively clean up the working copy, removing locks, resuming unfinished operations, etc."));
m_ImportDirsIntoCurrent = new KAction(i18n("Import folders into current"),"fileimport",KShortcut(),
TQT_TQOBJECT(this),TQT_SLOT(slotImportDirsIntoCurrent()),m_filesAction,"make_import_dirs_into_current");
m_ImportDirsIntoCurrent->setToolTip(i18n("Import folder content into current url"));
/* local only actions */
/* 1. actions on files AND dirs*/
m_AddCurrent = new KAction(i18n("Add selected files/dirs"),
"tdesvnadd",KShortcut(Key_Insert),m_SvnWrapper,TQT_SLOT(slotAdd()),m_filesAction,"make_svn_add");
m_AddCurrent->setToolTip(i18n("Adding selected files and/or directories to repository"));
tmp_action = new KAction("Add selected files/dirs recursive",
"tdesvnaddrecursive",KShortcut(CTRL+Key_Insert),m_SvnWrapper,TQT_SLOT(slotAddRec()),m_filesAction,"make_svn_addrec");
tmp_action->setToolTip(i18n("Adding selected files and/or directories to repository and all subitems of folders"));
m_DelCurrent = new KAction(i18n("Delete selected files/dirs"),"tdesvndelete",
KShortcut(Key_Delete),TQT_TQOBJECT(this),TQT_SLOT(slotDelete()),m_filesAction,"make_svn_remove");
m_DelCurrent->setToolTip(i18n("Deleting selected files and/or directories from repository"));
m_RevertAction = new KAction(i18n("Revert current changes"),"revert",
KShortcut(),m_SvnWrapper,TQT_SLOT(slotRevert()),m_filesAction,"make_svn_revert");
m_ResolvedAction = new KAction(i18n("Mark resolved"),KShortcut(),
TQT_TQOBJECT(this),TQT_SLOT(slotResolved()),m_filesAction,"make_resolved");
m_ResolvedAction->setToolTip(i18n("Marking files or dirs resolved"));
tmp_action = new KAction(i18n("Resolve conflicts"),KShortcut(),
TQT_TQOBJECT(this),TQT_SLOT(slotTryResolve()),m_filesAction,"make_try_resolve");
m_IgnoreAction = new KAction(i18n("Ignore/Unignore current item"),KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotIgnore()),m_filesAction,"make_svn_ignore");
m_UpdateHead = new KAction(i18n("Update to head"),"tdesvnupdate",
KShortcut(),m_SvnWrapper,TQT_SLOT(slotUpdateHeadRec()),m_filesAction,"make_svn_headupdate");
m_UpdateRev = new KAction(i18n("Update to revision..."),"tdesvnupdate",
KShortcut(),m_SvnWrapper,TQT_SLOT(slotUpdateTo()),m_filesAction,"make_svn_revupdate");
m_commitAction = new KAction(i18n("Commit"),"tdesvncommit",
KShortcut("CTRL+#"),m_SvnWrapper,TQT_SLOT(slotCommit()),m_filesAction,"make_svn_commit");
tmp_action = new KAction(i18n("Diff local changes"),"tdesvndiff",
KShortcut(CTRL+Key_D),TQT_TQOBJECT(this),TQT_SLOT(slotSimpleBaseDiff()),m_filesAction,"make_svn_basediff");
tmp_action->setToolTip(i18n("Diff working copy against BASE (last checked out version) - doesn't require access to repository"));
tmp_action = new KAction(i18n("Diff against HEAD"),"tdesvndiff",
KShortcut(CTRL+Key_H),TQT_TQOBJECT(this),TQT_SLOT(slotSimpleHeadDiff()),m_filesAction,"make_svn_headdiff");
tmp_action->setToolTip(i18n("Diff working copy against HEAD (last checked in version)- requires access to repository"));
tmp_action = new KAction(i18n("Diff items"),"tdesvndiff",
KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotDiffPathes()),m_filesAction,"make_svn_itemsdiff");
tmp_action->setToolTip(i18n("Diff two items"));
m_MergeRevisionAction = new KAction(i18n("Merge two revisions"),"tdesvnmerge",
KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotMergeRevisions()),m_filesAction,"make_svn_merge_revisions");
m_MergeRevisionAction->setToolTip(i18n("Merge two revisions of this entry into itself"));
tmp_action=new KAction(i18n("Merge..."),"tdesvnmerge",
KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotMerge()),m_filesAction,"make_svn_merge");
tmp_action->setToolTip("Merge repository path into current worky copy path or current repository path into a target");
tmp_action=new KAction( i18n( "Open With..." ), 0, TQT_TQOBJECT(this), TQT_SLOT( slotOpenWith() ), m_filesAction, "openwith" );
/* remote actions only */
m_CheckoutCurrentAction = new KAction(i18n("Checkout current repository path"),"tdesvncheckout",KShortcut(),
m_SvnWrapper,TQT_SLOT(slotCheckoutCurrent()),m_filesAction,"make_svn_checkout_current");
m_ExportCurrentAction = new KAction(i18n("Export current repository path"),"tdesvnexport",KShortcut(),
m_SvnWrapper,TQT_SLOT(slotExportCurrent()),m_filesAction,"make_svn_export_current");
new KAction(i18n("Select browse revision"),KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotSelectBrowsingRevision()),m_filesAction,"switch_browse_revision");
/* independe actions */
m_CheckoutAction = new KAction(i18n("Checkout a repository"),"tdesvncheckout",
KShortcut(),m_SvnWrapper,TQT_SLOT(slotCheckout()),m_filesAction,"make_svn_checkout");
m_ExportAction = new KAction(i18n("Export a repository"),"tdesvnexport",
KShortcut(),m_SvnWrapper,TQT_SLOT(slotExport()),m_filesAction,"make_svn_export");
m_RefreshViewAction = new KAction(i18n("Refresh view"),"reload",KShortcut(Key_F5),TQT_TQOBJECT(this),TQT_SLOT(refreshCurrentTree()),m_filesAction,"make_view_refresh");
new KAction(i18n("Diff revisions"),"tdesvndiff",KShortcut(),TQT_TQOBJECT(this),TQT_SLOT(slotDiffRevisions()),m_filesAction,"make_revisions_diff");
/* folding options */
tmp_action = new KAction( i18n("Unfold File Tree"), 0, TQT_TQOBJECT(this) , TQT_SLOT(slotUnfoldTree()), m_filesAction, "view_unfold_tree" );
tmp_action->setToolTip(i18n("Opens all branches of the file tree"));
tmp_action = new KAction( i18n("Fold File Tree"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotFoldTree()), m_filesAction, "view_fold_tree" );
tmp_action->setToolTip(i18n("Closes all branches of the file tree"));
/* caching */
tmp_action = new KAction( i18n("Update log cache"),0,TQT_TQOBJECT(this),TQT_SLOT(slotUpdateLogCache()),m_filesAction,"update_log_cache" );
tmp_action->setToolTip(i18n("Update the log cache for current repository"));
/* tmp_action = new KAction( i18n("Stop update log cache"),0,this,TQT_SLOT(slotUpdateLogCache()),m_filesAction,"stop_update_log_cache" );
tmp_action->setToolTip(i18n("Stop the update of the log cache"));
*/
enableActions();
m_filesAction->setHighlightingEnabled(true);
}
KActionCollection*tdesvnfilelist::filesActions()
{
return m_filesAction;
}
FileListViewItemList* tdesvnfilelist::allSelected()
{
if (!m_SelectedItems) {
m_SelectedItems = new FileListViewItemList;
}
return m_SelectedItems;
}
void tdesvnfilelist::SelectionList(SvnItemList*target)
{
if (!m_SelectedItems||!target) return;
FileListViewItemListIterator iter(*m_SelectedItems);
FileListViewItem*cur;
while ( (cur=iter.current())!=0) {
++iter;
target->append(cur);
}
}
SvnItem*tdesvnfilelist::SelectedOrMain()
{
if (singleSelected()!=0) {
return singleSelected();
}
if (isWorkingCopy()&&firstChild()) {
return static_cast<FileListViewItem*>(firstChild());
}
return 0;
}
KURL::List tdesvnfilelist::selectedUrls()
{
KURL::List lst;
FileListViewItemList*ls = allSelected();
FileListViewItemListIterator it(*ls);
FileListViewItem*cur;
while ( (cur=it.current())!=0) {
++it;
/* for putting it to outside we must convert it to KIO urls */
lst.append(cur->kdeName(m_pList->m_remoteRevision));
}
return lst;
}
TQWidget*tdesvnfilelist::realWidget()
{
return this;
}
FileListViewItem* tdesvnfilelist::singleSelected()
{
if (m_SelectedItems && m_SelectedItems->count()==1) {
return m_SelectedItems->at(0);
}
return 0;
}
SvnItem*tdesvnfilelist::Selected()
{
return singleSelected();
}
void tdesvnfilelist::_openURL(const TQString&url)
{
openURL(url,true);
emit sigUrlChanged(baseUri());
}
bool tdesvnfilelist::openURL( const KURL &url,bool noReinit )
{
CursorStack a;
m_SvnWrapper->killallThreads();
clear();
emit sigProplist(svn::PathPropertiesMapListPtr(new svn::PathPropertiesMapList()),false,TQString(""));
m_Dirsread.clear();
if (m_SelectedItems) {
m_SelectedItems->clear();
}
m_LastException="";
delete m_pList->m_DirWatch;
m_pList->m_DirWatch=0;
m_pList->dirItems.clear();
m_pList->stopDirTimer();
if (!noReinit) m_SvnWrapper->reInitClient();
TQString query = url.query();
KURL _url = url;
TQString proto = svn::Url::transformProtokoll(url.protocol());
_url.cleanPath(true);
_url.setProtocol(proto);
proto = _url.url(-1);
TQStringList s = TQStringList::split("?",proto);
if (s.size()>1) {
setBaseUri(s[0]);
} else {
setBaseUri(proto);
}
setWorkingCopy(false);
setNetworked(false);
m_pList->m_remoteRevision=svn::Revision::HEAD;
TQString _dummy;
if (!TQString::compare("svn+file",url.protocol())) {
setBaseUri("file://"+url.path());
} else {
if (url.isLocalFile()) {
TQString s = url.path();
while(s.endsWith("/")) {
s.remove(s.length()-1,1);
}
TQFileInfo fi(s);
if (fi.exists() && fi.isSymLink()) {
TQString sl = fi.readLink();
if (sl.startsWith("/")) {
setBaseUri(sl);
} else {
fi.setFile(fi.dirPath()+"/"+sl);
setBaseUri(fi.absFilePath());
}
} else {
setBaseUri(url.path());
}
if (m_SvnWrapper->isLocalWorkingCopy(baseUri(),_dummy)) {
setWorkingCopy(true);
} else {
// yes! KURL sometimes makes a correct localfile url (file:///)
// to a simple file:/ - that breakes subversion lib. so we make sure
// that we have a correct url
setBaseUri("file://"+baseUri());
}
} else {
setNetworked(true);
if (!Kdesvnsettings::network_on()) {
setBaseUri("");
setNetworked(false);
clear();
KMessageBox::error(this,i18n("Networked URL to open but networking is disabled!"));
emit changeCaption("");
emit sigUrlOpend(false);
return false;
}
}
}
if (query.length()>1) {
TQMap<TQString,TQString> q = url.queryItems();
if (q.find("rev")!=q.end()) {
TQString v = q["rev"];
svn::Revision tmp;
m_SvnWrapper->svnclient()->url2Revision(v,m_pList->m_remoteRevision,tmp);
if (m_pList->m_remoteRevision==svn::Revision::UNDEFINED) {
m_pList->m_remoteRevision = svn::Revision::HEAD;
}
}
}
if (url.protocol()=="svn+ssh"||
url.protocol()=="ksvn+ssh") {
SshAgent ssh;
ssh.addSshIdentities();
}
m_SvnWrapper->clearUpdateCache();
if (isWorkingCopy()) {
m_pList->m_DirWatch=new KDirWatch(TQT_TQOBJECT(this));
connect(m_pList->m_DirWatch,TQT_SIGNAL(dirty(const TQString&)),this,TQT_SLOT(slotDirItemDirty(const TQString&)));
connect(m_pList->m_DirWatch,TQT_SIGNAL(created(const TQString&)),this,TQT_SLOT(slotDirItemCreated(const TQString&)));
connect(m_pList->m_DirWatch,TQT_SIGNAL(deleted(const TQString&)),this,TQT_SLOT(slotDirItemDeleted(const TQString&)));
/* seems that recursive does not work */
if (m_pList->m_DirWatch) {
m_pList->m_DirWatch->addDir(baseUri()+"/",false,false);
m_pList->m_DirWatch->startScan(true);
}
}
bool result = checkDirs(baseUri(),0);
if (result && isWorkingCopy()) {
chdir(baseUri().local8Bit());
if (firstChild()) firstChild()->setOpen(true);
}
if (!result) {
setBaseUri("");
setNetworked(false);
clear();
}
m_pList->m_fileTip->setOptions(!isNetworked()&&Kdesvnsettings::display_file_tips()&&
TQToolTip::isGloballyEnabled(),true,6);
if (result && isWorkingCopy()) {
m_SvnWrapper->createModifiedCache(baseUri());
if (Kdesvnsettings::start_updates_check_on_open()) {
slotCheckUpdates();
}
}
if (Kdesvnsettings::log_cache_on_open()) {
kdDebug()<<"Starting logcache"<<endl;
m_SvnWrapper->startFillCache(baseUri());
}
emit changeCaption(baseUri());
emit sigUrlOpend(result);
TQTimer::singleShot(1,this,TQT_SLOT(readSupportData()));
enableActions();
return result;
}
void tdesvnfilelist::closeMe()
{
m_SvnWrapper->killallThreads();
selectAll(false);
clear();
setWorkingCopy("");
setNetworked(false);
setWorkingCopy(false);
setBaseUri("");
emit changeCaption("");
emit sigUrlOpend(false);
enableActions();
m_SvnWrapper->reInitClient();
delete m_pList->m_DirWatch;
m_pList->m_DirWatch = 0;
m_pList->m_fileTip->setItem(0);
}
bool tdesvnfilelist::checkDirs(const TQString&_what,FileListViewItem * _parent)
{
TQString what = _what;
svn::StatusEntries dlist;
while (what.endsWith("/")) {
what.truncate(what.length()-1);
}
// prevent this from checking unversioned folder. FIXME: what happen when we do open url on a non-working-copy folder??
if (!isWorkingCopy()|| (!_parent) || ((_parent) && (_parent->isVersioned()))) {
if (!m_SvnWrapper->makeStatus(what,dlist,m_pList->m_remoteRevision) ) {
kdDebug() << "unable makeStatus" <<endl;
return false;
}
} else {
checkUnversionedDirs(_parent);
return true;
}
svn::StatusEntries neweritems;
m_SvnWrapper->getaddedItems(what,neweritems);
dlist+=neweritems;
bool ownupdates = true;
//kdDebug() << "makeStatus on " << what << " created: " << dlist.count() << "items" <<endl;
if (isUpdatesEnabled()) {
viewport()->setUpdatesEnabled(false);
} else {
ownupdates=false;
}
svn::StatusEntries::iterator it = dlist.begin();
FileListViewItem * pitem = 0;
bool main_found = false;
for (;it!=dlist.end();++it) {
//kdDebug() << "iterate over it: " << (*it)->entry().url() << endl;
// current item is not versioned
if (!(*it)->isVersioned() && !filterOut((*it))) {
// if empty, we may want to create a default svn::Status for each folder inside this _parent
// iterate over TQDir and create new filelistviewitem
checkUnversionedDirs(_parent);
}
if ((*it)->path()==what||TQString::compare((*it)->entry().url(),what)==0){
if (!_parent) {
pitem = new FileListViewItem(this,*it);
//kdDebug()<< "CheckDirs::creating new FileListViewitem as parent " + (*it)->path() << endl;
m_Dirsread[pitem->fullName()]=true;
pitem->setDropEnabled(true);
}
dlist.erase(it);
main_found = true;
break;
}
}
if (_parent) {
pitem = _parent;
}
insertDirs(pitem,dlist);
if (ownupdates) {
kdDebug()<<"Enable update"<<endl;
viewport()->setUpdatesEnabled(true);
viewport()->repaint();
}
return true;
}
void tdesvnfilelist::insertDirs(FileListViewItem * _parent,svn::StatusEntries&dlist)
{
svn::StatusEntries::iterator it;
#if 0
KFileItemList oneItem;
#endif
TQTime _t;
_t.start();
for (it = dlist.begin();it!=dlist.end();++it) {
/* if (_t.elapsed()>300) {
viewport()->setUpdatesEnabled(true);
viewport()->repaint();
viewport()->setUpdatesEnabled(false);
_t.restart();
}*/
if (filterOut((*it)))
{
continue;
}
FileListViewItem * item;
if (!_parent) {
item = new FileListViewItem(this,*it);
} else {
if ( (item = _parent->findChild( (*it)->path() )) ) {
delete item;
}
item = new FileListViewItem(this,_parent,*it);
}
if (item->isDir()) {
m_Dirsread[item->fullName()]=false;
item->setDropEnabled(true);
if (isWorkingCopy()) {
m_pList->m_DirWatch->addDir(item->fullName());
}
} else if (isWorkingCopy()) {
m_pList->m_DirWatch->addFile(item->fullName());
}
}
}
/* newdir is the NEW directory! just required if local */
void tdesvnfilelist::slotDirAdded(const TQString&newdir,FileListViewItem*k)
{
if (k) {
k->refreshStatus();
}
if (!isWorkingCopy()) {
if (k) {
k->removeChilds();
m_Dirsread[k->fullName()]=false;
if (checkDirs(k->fullName(),k)) {
m_Dirsread[k->fullName()]=true;
} else {
kdDebug()<<"Checkdirs failed"<<endl;
}
return;
}
TQListViewItem*temp;
while ((temp=firstChild())) {
delete temp;
}
m_Dirsread.clear();
checkDirs(baseUri(),0);
return;
}
svn::StatusPtr stat;
try {
stat = m_SvnWrapper->svnclient()->singleStatus(newdir);
} catch (const svn::ClientException&e) {
m_LastException = e.msg();
kdDebug()<<"Catched on singlestatus"<< endl;
emit sigLogMessage(m_LastException);
return;
}
FileListViewItem * item,*pitem;
pitem = k;
if (!pitem) {
pitem = (FileListViewItem*)firstChild();
if (pitem->fullName()!=baseUri()) {
pitem = 0;
}
}
if (!pitem) {
item = new FileListViewItem(this,stat);
} else {
item = new FileListViewItem(this,pitem,stat);
}
if (item->isDir()) {
m_Dirsread[item->fullName()]=false;
item->setDropEnabled(true);
if (isWorkingCopy()) {
m_pList->m_DirWatch->addDir(item->fullName());
}
} else if (isWorkingCopy()) {
m_pList->m_DirWatch->addFile(item->fullName());
}
}
tdesvnfilelist::~tdesvnfilelist()
{
delete m_pList;
delete m_SelectedItems;
SshAgent ssh;
ssh.killSshAgent();
}
void tdesvnfilelist::slotItemRead(TQListViewItem*aItem)
{
if (!aItem) return;
CursorStack a(TQt::BusyCursor);
FileListViewItem* k = static_cast<FileListViewItem*>( aItem );
bool _ex = true;
if (isWorkingCopy()) {
TQDir d(k->fullName()); //FIXME: remove this as soon as we've been able to set entry->kind in Checkdirs
_ex = k->isDir()||d.exists();
} else {
_ex = k->isDir();
}
if (_ex &&(m_Dirsread.find(k->fullName())==m_Dirsread.end()||m_Dirsread[k->fullName()]==false)) {
if (checkDirs(k->fullName(),k)) {
m_Dirsread[k->fullName()]=true;
} else {
emit sigListError();
}
}
}
void tdesvnfilelist::slotReinitItem(SvnItem*item)
{
if (!item) {
kdDebug()<<"tdesvnfilelist::slotReinitItem(SvnItem*item): item == null" << endl;
return;
}
FileListViewItem*k = item->fItem();
if (!k) {
kdDebug()<<"tdesvnfilelist::slotReinitItem(SvnItem*item): k == null" << endl;
}
refreshItem(k);
if (!k) {
return;
}
if (k->isDir()) {
k->removeChilds();
m_Dirsread[k->fullName()]=false;;
}
}
void tdesvnfilelist::enableActions()
{
bool isopen = baseUri().length()>0;
int c = allSelected()->count();
bool single = c==1&&isopen;
bool multi = c>1&&isopen;
bool none = c==0&&isopen;
bool dir = false;
bool unique = uniqueTypeSelected();
bool remote_enabled=isopen&&m_SvnWrapper->doNetworking();
if (single && allSelected()->at(0)->isDir()) {
dir = true;
}
bool conflicted = single && allSelected()->at(0)->isConflicted();
KAction * temp = 0;
/* local and remote actions */
/* 1. actions on dirs AND files */
temp = filesActions()->action("make_svn_log");
if (temp) {
temp->setEnabled(single||none);
}
temp = filesActions()->action("make_last_change");
if (temp) {
temp->setEnabled(isopen);
}
temp = filesActions()->action("make_svn_log_full");
if (temp) {
temp->setEnabled(single||none);
}
temp = filesActions()->action("make_svn_tree");
if (temp) {
temp->setEnabled(single||none);
}
temp = filesActions()->action("make_svn_partialtree");
if (temp) {
temp->setEnabled(single||none);
}
temp = filesActions()->action("make_svn_property");
if (temp) {
temp->setEnabled(single);
}
temp = filesActions()->action("get_svn_property");
if (temp) {
temp->setEnabled(single);
}
m_DelCurrent->setEnabled( (multi||single));
m_LockAction->setEnabled( (multi||single));
m_UnlockAction->setEnabled( (multi||single));
m_IgnoreAction->setEnabled((single)&&singleSelected()->parent()!=0&&!singleSelected()->isRealVersioned());
m_RenameAction->setEnabled(single && (!isWorkingCopy()||singleSelected()!=firstChild()));
m_CopyAction->setEnabled(single && (!isWorkingCopy()||singleSelected()!=firstChild()));
/* 2. only on files */
m_BlameAction->setEnabled(single&&!dir&&remote_enabled);
m_BlameRangeAction->setEnabled(single&&!dir&&remote_enabled);
m_CatAction->setEnabled(single&&!dir);
/* 3. actions only on dirs */
m_MkdirAction->setEnabled(dir||none && isopen);
m_switchRepository->setEnabled(isWorkingCopy()&& (single||none));
m_changeToRepository->setEnabled(isWorkingCopy());
m_ImportDirsIntoCurrent->setEnabled(dir);
temp = filesActions()->action("make_svn_relocate");
if (temp) {
temp->setEnabled(isWorkingCopy()&& (single||none));
}
m_ExportCurrentAction->setEnabled(((single&&dir)||none));
/* local only actions */
/* 1. actions on files AND dirs*/
m_AddCurrent->setEnabled( (multi||single) && isWorkingCopy());
m_RevertAction->setEnabled( (multi||single) && isWorkingCopy());
m_ResolvedAction->setEnabled( (multi||single) && isWorkingCopy());
temp = filesActions()->action("make_try_resolve");
if (temp) {
temp->setEnabled(conflicted && !dir);
}
m_InfoAction->setEnabled(isopen);
m_MergeRevisionAction->setEnabled(single&&isWorkingCopy());
temp = filesActions()->action("make_svn_merge");
if (temp) {
temp->setEnabled(single||none);
}
temp = filesActions()->action("make_svn_addrec");
if (temp) {
temp->setEnabled( (multi||single) && isWorkingCopy());
}
m_UpdateHead->setEnabled(isWorkingCopy()&&isopen&&remote_enabled);
m_UpdateRev->setEnabled(isWorkingCopy()&&isopen&&remote_enabled);
m_commitAction->setEnabled(isWorkingCopy()&&isopen&&remote_enabled);
temp = filesActions()->action("make_svn_basediff");
if (temp) {
temp->setEnabled(isWorkingCopy()&&(single||none));
}
temp = filesActions()->action("make_svn_headdiff");
if (temp) {
temp->setEnabled(isWorkingCopy()&&(single||none)&&remote_enabled);
}
/// @todo check if all items have same type
temp = filesActions()->action("make_svn_itemsdiff");
if (temp) {
temp->setEnabled(multi && c==2 && unique && remote_enabled);
}
/* 2. on dirs only */
m_CleanupAction->setEnabled(isWorkingCopy()&& (dir||none));
temp = filesActions()->action("make_check_unversioned");
if (temp) {
temp->setEnabled(isWorkingCopy()&& ((dir&&single) || none));
}
/* remote actions only */
m_CheckoutCurrentAction->setEnabled( ((single&&dir)||none) && !isWorkingCopy() && remote_enabled);
/* independ actions */
m_CheckoutAction->setEnabled(remote_enabled);
m_ExportAction->setEnabled(true);
m_RefreshViewAction->setEnabled(isopen);
temp = filesActions()->action("make_revisions_diff");
if (temp) {
temp->setEnabled(isopen);
}
temp = filesActions()->action("make_revisions_cat");
if (temp) {
temp->setEnabled(isopen && !dir && single);
}
temp = filesActions()->action("switch_browse_revision");
if (temp) {
temp->setEnabled(!isWorkingCopy()&&isopen);
}
temp = filesActions()->action("make_check_updates");
if (temp) {
temp->setEnabled(isWorkingCopy()&&isopen && remote_enabled);
}
temp = filesActions()->action("openwith");
if (temp) {
temp->setEnabled(kapp->authorizeKAction("openwith")&&single&&!dir);
}
temp = filesActions()->action("update_log_cache");
if (temp) {
temp->setEnabled(remote_enabled);
if (!m_SvnWrapper->threadRunning(SvnActions::fillcachethread)) {
temp->setText(i18n("Update log cache"));
} else {
temp->setText(i18n("Stop updating the logcache"));
}
}
}
void tdesvnfilelist::slotSelectionChanged()
{
m_pList->stopProptimer();
if (m_SelectedItems==0) {
m_SelectedItems = new FileListViewItemList;
m_SelectedItems->setAutoDelete(false);
}
m_SelectedItems->clear();
TQListViewItemIterator it( this, TQListViewItemIterator::Selected );
while ( it.current() ) {
m_SelectedItems->append( static_cast<FileListViewItem*>(it.current()) );
++it;
}
enableActions();
m_pList->startProptimer();
}
/*!
\fn tdesvnfilelist::slotClientException(const TQString&)
*/
void tdesvnfilelist::slotClientException(const TQString&what)
{
emit sigLogMessage(what);
KMessageBox::sorry(TQT_TQWIDGET(TDEApplication::activeModalWidget()),what,i18n("SVN Error"));
}
/*!
\fn tdesvnfilelist::slotNotifyMessage(const TQString&)
*/
void tdesvnfilelist::slotNotifyMessage(const TQString&what)
{
emit sigLogMessage(what);
kapp->processEvents(20);
}
void tdesvnfilelist::slotChangeToRepository()
{
if (!isWorkingCopy()) {
return;
}
FileListViewItem*k = static_cast<FileListViewItem*>(firstChild());
/* huh... */
if (!k) return;
svn::InfoEntry i;
if (!m_SvnWrapper->singleInfo(k->Url(),svn::Revision::UNDEFINED,i)) {
return;
}
if (i.reposRoot().isEmpty()) {
KMessageBox::sorry(TQT_TQWIDGET(TDEApplication::activeModalWidget()),i18n("Could not retrieve repository of working copy."),i18n("SVN Error"));
} else {
sigSwitchUrl(i.reposRoot());
}
}
void tdesvnfilelist::slotItemDoubleClicked(TQListViewItem*item)
{
if (!item) return;
FileListViewItem*fki = static_cast<FileListViewItem*>(item);
if (fki->isDir()) {
if (fki->isOpen()) {
fki->setOpen(false);
} else {
fki->setOpen(true);
}
return;
}
svn::Revision rev(isWorkingCopy()?svn::Revision::UNDEFINED:m_pList->m_remoteRevision);
TQString feditor = Kdesvnsettings::external_display();
if ( feditor.compare("default") == 0 ) {
KURL::List lst;
lst.append(fki->kdeName(rev));
KTrader::OfferList li = offersList(fki,true);
if (li.count()==0||li.first()->exec().isEmpty()) {
li = offersList(fki);
}
if (li.count()>0&&!li.first()->exec().isEmpty()) {
KService::Ptr ptr = li.first();
KRun::run( *ptr, lst);
} else {
KRun::displayOpenWithDialog(lst);
}
} else {
if ( KRun::runCommand(feditor + " " + fki->kdeName(rev).prettyURL()) <= 0) {
KMessageBox::error(this,i18n("Failed: %1 %2").arg(feditor).arg(fki->fullName()));
}
}
}
void tdesvnfilelist::slotCleanupAction()
{
if (!isWorkingCopy()) return;
FileListViewItem*which= singleSelected();
if (!which) which = static_cast<FileListViewItem*>(firstChild());
if (!which||!which->isDir()) return;
if (m_SvnWrapper->makeCleanup(which->fullName())) {
which->refreshStatus(true);
}
}
void tdesvnfilelist::slotResolved()
{
if (!isWorkingCopy()) return;
FileListViewItem*which= singleSelected();
if (!which) which = static_cast<FileListViewItem*>(firstChild());
if (!which) return;
m_SvnWrapper->slotResolved(which->fullName());
which->refreshStatus(true);
slotRescanIcons(false);
}
void tdesvnfilelist::slotTryResolve()
{
if (!isWorkingCopy()) return;
FileListViewItem*which= singleSelected();
if (!which || which->isDir()) {
return;
}
m_SvnWrapper->slotResolve(which->fullName());
}
template<class T> KDialogBase* tdesvnfilelist::createDialog(T**ptr,const TQString&_head,bool OkCancel,const char*name,bool showHelp)
{
int buttons = KDialogBase::Ok;
if (OkCancel) {
buttons = buttons|KDialogBase::Cancel;
}
if (showHelp) {
buttons = buttons|KDialogBase::Help;
}
KDialogBase * dlg = new KDialogBase(
TQT_TQWIDGET(TQT_TQWIDGET(TDEApplication::activeModalWidget())),
name,
true,
_head,
buttons);
if (!dlg) return dlg;
TQWidget* Dialog1Layout = dlg->makeVBoxMainWidget();
*ptr = new T(Dialog1Layout);
dlg->resize(dlg->configDialogSize(*(Kdesvnsettings::self()->config()),name?name:"standard_size"));
return dlg;
}
void tdesvnfilelist::slotImportDirsIntoCurrent()
{
slotImportIntoCurrent(true);
}
/*!
\fn tdesvnfilelist::slotImportIntoCurrent()
*/
void tdesvnfilelist::slotImportIntoCurrent(bool dirs)
{
if (allSelected()->count()>1) {
KMessageBox::error(this,i18n("Cannot import into multiple targets!"));
return;
}
TQString targetUri;
if (allSelected()->count()==0) {
targetUri=baseUri();
} else {
targetUri = allSelected()->at(0)->Url();
}
KURL uri;
if (dirs) uri = KFileDialog::getExistingDirectory(TQString(),this,"Import files from folder");
else uri = KFileDialog::getImageOpenURL(TQString(),this,"Import file");
if (uri.url().isEmpty()) return;
if ( !uri.protocol().isEmpty() && uri.protocol()!="file") {
KMessageBox::error(this,i18n("Cannot import into remote targets!"));
return;
}
slotImportIntoDir(uri,targetUri,dirs);
}
void tdesvnfilelist::slotImportIntoDir(const KURL&importUrl,const TQString&target,bool dirs)
{
Logmsg_impl*ptr;
Importdir_logmsg*ptr2 = 0;
KDialogBase*dlg;
KURL uri = importUrl;
TQString targetUri = target;
while (targetUri.endsWith("/")) {
targetUri.truncate(targetUri.length()-1);
}
if (dirs) {
dlg = createDialog(&ptr2,TQString(i18n("Import log")),true,"import_log_msg");
ptr = ptr2;
ptr2->createDirboxDir("\""+uri.fileName(true)+"\"");
} else {
dlg = createDialog(&ptr,TQString(i18n("Import log")),true,"import_log_msg");
}
if (!dlg) return;
ptr->initHistory();
if (dlg->exec()!=TQDialog::Accepted) {
ptr->saveHistory(true);
dlg->saveDialogSize(*(Kdesvnsettings::self()->config()),"import_log_msg",false);
delete dlg;
return;
}
dlg->saveDialogSize(*(Kdesvnsettings::self()->config()),"import_log_msg",false);
TQString logMessage = ptr->getMessage();
svn::Depth rec = ptr->getDepth();
ptr->saveHistory(false);
uri.setProtocol("");
TQString iurl = uri.path();
while (iurl.endsWith("/")) {
iurl.truncate(iurl.length()-1);
}
if (dirs && ptr2 && ptr2->createDir()) {
targetUri+= "/"+uri.fileName(true);
}
if (ptr2) {
m_SvnWrapper->slotImport(iurl,targetUri,logMessage,rec,ptr2->noIgnore(),ptr2->ignoreUnknownNodes());
} else {
m_SvnWrapper->slotImport(iurl,targetUri,logMessage,rec,false,false);
}
if (!isWorkingCopy()) {
if (allSelected()->count()==0) {
refreshCurrentTree();
} else {
refreshCurrent(allSelected()->at(0));
}
}
delete dlg;
}
void tdesvnfilelist::readSupportData()
{
/// this moment empty cause no usagedata explicit used by tdesvnfilelist
}
void tdesvnfilelist::refreshCurrentTree()
{
TQTime t;
t.start();
FileListViewItem*item = static_cast<FileListViewItem*>(firstChild());
if (!item) return;
//m_pList->stopScan();
m_pList->m_fileTip->setItem(0);
kapp->processEvents();
setUpdatesEnabled(false);
if (item->fullName()==baseUri()) {
if (!refreshItem(item)) {
setUpdatesEnabled(true);
viewport()->repaint();
return;
} else {
refreshRecursive(item);
}
} else {
refreshRecursive(0);
}
if (isWorkingCopy()) {
m_SvnWrapper->createModifiedCache(baseUri());
}
kdDebug()<<"Refresh time: "<<t.elapsed()<<" ms"<<endl;
setUpdatesEnabled(true);
viewport()->repaint();
TQTimer::singleShot(1,this,TQT_SLOT(readSupportData()));
//m_pList->startScan();
}
void tdesvnfilelist::refreshCurrent(SvnItem*cur)
{
if (!cur||!cur->fItem()) {
refreshCurrentTree();
return;
}
kapp->processEvents();
setUpdatesEnabled(false);
refreshRecursive(cur->fItem());
setUpdatesEnabled(true);
viewport()->repaint();
}
bool tdesvnfilelist::refreshRecursive(FileListViewItem*_parent,bool down)
{
FileListViewItem*item;
if (_parent) {
item = static_cast<FileListViewItem*>(_parent->firstChild());
} else {
item = static_cast<FileListViewItem*>(firstChild());
}
if (!item) return false;
kapp->processEvents();
FileListViewItemList currentSync;
currentSync.setAutoDelete(false);
while (item) {
currentSync.append(item);
item = static_cast<FileListViewItem*>(item->nextSibling());
}
TQString what = (_parent!=0?_parent->fullName():baseUri());
svn::StatusEntries dlist;
if (!m_SvnWrapper->makeStatus(what,dlist,m_pList->m_remoteRevision)) {
kdDebug()<<"Fehler bei makestatus fuer "<<what <<endl;
return false;
}
if (isWorkingCopy()) {
svn::StatusEntries neweritems;
m_SvnWrapper->getaddedItems(what,neweritems);
dlist+=neweritems;
}
svn::StatusEntries::iterator it = dlist.begin();
FileListViewItem*k;
bool gotit = false;
bool dispchanged = false;
for (;it!=dlist.end();++it) {
gotit = false;
if ((*it)->path()==what) {
continue;
}
FileListViewItemListIterator clistIter(currentSync);
while ( (k=clistIter.current()) ) {
++clistIter;
if (k->fullName()==(*it)->path()) {
currentSync.removeRef(k);
k->updateStatus(*it);
if (filterOut(k)) {
dispchanged=true;
delete k;
}
gotit = true;
break;
}
}
if (!gotit &&!filterOut((*it)) ) {
dispchanged = true;
FileListViewItem * item;
if (!_parent) {
item = new FileListViewItem(this,*it);
} else {
item = new FileListViewItem(this,_parent,*it);
}
if (item->isDir()) {
m_Dirsread[item->fullName()]=false;
item->setDropEnabled(true);
}
if (isWorkingCopy()) {
if (item->isDir()) {
m_pList->m_DirWatch->addDir(item->fullName());
} else {
m_pList->m_DirWatch->addFile(item->fullName());
}
}
}
}
FileListViewItemListIterator dIter(currentSync);
#ifndef NDEBUG
slotSelectionChanged();
kdDebug() << "Selected items " << m_SelectedItems->count()<< endl;
#endif
while ( (k=dIter.current()) ) {
++dIter;
delete k;
// @todo just for debugging!
#ifndef NDEBUG
m_SelectedItems->clear();
TQListViewItemIterator qlvit( this, TQListViewItemIterator::Selected );
while ( qlvit.current() ) {
m_SelectedItems->append( static_cast<FileListViewItem*>(qlvit.current()) );
++qlvit;
}
kdDebug() << "Selected items " << m_SelectedItems->count() << endl;
#endif
}
if (_parent) {
item = static_cast<FileListViewItem*>(_parent->firstChild());
} else {
item = static_cast<FileListViewItem*>(firstChild());
}
if (!down) {
return dispchanged;
}
while (item) {
if (item->isDir()) {
if ((m_Dirsread.find(item->fullName())!=m_Dirsread.end()&&m_Dirsread[item->fullName()]==true)) {
if (item->childCount()==0) {
checkDirs(item->fullName(),item);
dispchanged = true;
} else {
dispchanged = refreshRecursive(item)?true:dispchanged;
}
}
}
item = static_cast<FileListViewItem*>(item->nextSibling());
}
return dispchanged;
}
KTrader::OfferList tdesvnfilelist::offersList(SvnItem*item,bool execOnly)
{
KTrader::OfferList offers;
if (!item) {
return offers;
}
TQString constraint;
if (execOnly) {
constraint = "Type == 'Application' or (exist Exec)";
} else {
constraint = "Type == 'Application'";
}
offers = KTrader::self()->query(item->mimeType()->name(), constraint);
return offers;
}
void tdesvnfilelist::slotContextMenuRequested(TQListViewItem */* _item */, const TQPoint &, int)
{
// FileListViewItem*item = static_cast<FileListViewItem*>(_item);
bool isopen = baseUri().length()>0;
SvnItemList l;
SelectionList(&l);
TQString menuname;
if (!isopen) {
menuname="empty";
} else if (isWorkingCopy()) {
menuname="local";
} else {
menuname="remote";
}
if (l.count()==0) {
menuname+="_general";
} else if (l.count()>1){
menuname+="_context_multi";
} else {
menuname+="_context_single";
if (isWorkingCopy()) {
if (l.at(0)->isRealVersioned()) {
if (l.at(0)->isConflicted()) {
menuname+="_conflicted";
} else {
menuname+="_versioned";
if (l.at(0)->isDir()) {
menuname+="_dir";
}
}
} else {
menuname+="_unversioned";
}
} else if (l.at(0)->isDir()) {
menuname+="_dir";
}
}
TQWidget * target;
emit sigShowPopup(menuname,&target);
TQPopupMenu *popup = static_cast<TQPopupMenu *>(target);
if (!popup) {
kdDebug()<<"Error getting popupMenu"<<endl;
return;
}
KTrader::OfferList offers;
OpenContextmenu*me=0;
KAction*temp = 0;
int id = -1;
if (l.count()==1) offers = offersList(l.at(0));
if (l.count()==1&&!l.at(0)->isDir()) {
temp = filesActions()->action("openwith");
if (offers.count()>0) {
svn::Revision rev(isWorkingCopy()?svn::Revision::UNDEFINED:m_pList->m_remoteRevision);
me= new OpenContextmenu(l.at(0)->kdeName(rev),offers,0,0);
id = popup->insertItem(i18n("Open With..."),me);
} else {
temp = filesActions()->action("openwith");
if (temp) {
temp->plug(popup);
}
}
}
popup->exec(TQCursor::pos());
if (id>-1) {
popup->removeItem(id);
}
delete me;
if (temp) {
temp->unplug(popup);
}
}
/**
* Overridden virtuals for TQt drag 'n drop (XDND)
*/
void tdesvnfilelist::contentsDragEnterEvent(TQDragEnterEvent *event)
{
TQListViewItem*item;
bool ok = validDropEvent(event,item);
if (ok) {
event->accept();
} else {
event->ignore();
}
}
//void tdesvnfilelist::startDrag()
TQDragObject* tdesvnfilelist::dragObject()
{
m_pList->m_fileTip->setItem(0);
TQListViewItem * m_pressedItem = currentItem();
if (!m_pressedItem) {
return 0;
}
TQPixmap pixmap2;
KURL::List urls = selectedUrls();
if (urls.count()==0) {
return 0;
}
if (!viewport()->hasFocus()) {
kdDebug()<<"Set focus"<<endl;
viewport()->setFocus();
}
kdDebug() << "dragObject: " << urls << endl;
bool pixmap0Invalid = !m_pressedItem->pixmap(0) || m_pressedItem->pixmap(0)->isNull();
if (( urls.count() > 1 ) || (pixmap0Invalid)) {
int iconSize = Kdesvnsettings::listview_icon_size();;
iconSize = iconSize ? iconSize : tdesvnPartFactory::instance()->iconLoader()->currentSize( KIcon::Small ); // Default = small
pixmap2 = DesktopIcon( "kmultiple", iconSize );
if ( pixmap2.isNull() ) {
kdWarning() << "Could not find multiple pixmap" << endl;
}
}
KURLDrag *drag;
drag = new KURLDrag(urls,viewport());
/* workaround for KURL::Drag - it always forget the revision part on drop :( */
if (!isWorkingCopy()) {
TQStrList l;
TQString t;
KURL::List::ConstIterator it = urls.begin();
for (;it!=urls.end();++it) {
l.append((*it).prettyURL().ascii());
}
drag->setUris(l);
}
drag->setExportAsText(true);
if ( !pixmap2.isNull() )
drag->setPixmap( pixmap2 );
else if ( !pixmap0Invalid )
drag->setPixmap( *m_pressedItem->pixmap( 0 ) );
return drag;
}
void tdesvnfilelist::contentsDragLeaveEvent( TQDragLeaveEvent * )
{
cleanHighLighter();
}
bool tdesvnfilelist::acceptDrag(TQDropEvent *event)const
{
return KURLDrag::canDecode(event);
}
bool tdesvnfilelist::validDropEvent(TQDropEvent*event,TQListViewItem*&item)
{
if (!event) return false;
if (!isWorkingCopy()) {
if (m_pList->m_remoteRevision!=svn::Revision::HEAD) {
item = 0;
return false;
}
}
bool ok = false;
item = 0;
if (KURLDrag::canDecode(event)) {
KURL::List urlList;
KURLDrag::decode( event, urlList );
int count = urlList.count();
if (count>0) {
if (baseUri().length()==0) {
ok = true;
} else {
TQPoint vp = contentsToViewport( event->pos() );
item = isExecuteArea( vp ) ? itemAt( vp ) : 0L;
FileListViewItem*which=static_cast<FileListViewItem*>(item);
if (!isWorkingCopy()) {
if (event->source()!=viewport()){
ok = (!item || (which->isDir()))&&urlList[0].isLocalFile()&&count==1;
} else {
ok = (!item || (which->isDir() ));
}
} else {
ok = (which && (which->isDir()));
}
}
}
}
return ok;
}
void tdesvnfilelist::contentsDropEvent(TQDropEvent * event)
{
TQListViewItem *item = 0;
bool ok = validDropEvent(event,item);
cleanHighLighter();
if (ok) {
dropped(event,item);
} else {
event->ignore();
}
}
void tdesvnfilelist::contentsDragMoveEvent( TQDragMoveEvent* event)
{
TQListViewItem * item;
bool ok = validDropEvent(event,item);
if (item && item!=m_pList->dragOverItem) {
TQPoint vp = contentsToViewport( event->pos() );
m_pList->dragOverItem=item;
m_pList->dragOverPoint = vp;
TQRect tmpRect = drawItemHighlighter(0, m_pList->dragOverItem);
if (tmpRect!=m_pList->mOldDropHighlighter) {
cleanHighLighter();
m_pList->mOldDropHighlighter=tmpRect;
viewport()->repaint(tmpRect);
kapp->processEvents();
}
}
if (ok) {
event->accept();
} else {
event->ignore();
}
}
void tdesvnfilelist::viewportPaintEvent(TQPaintEvent *ev)
{
KListView::viewportPaintEvent(ev);
if (m_pList->mOldDropHighlighter.isValid() && ev->rect().intersects(m_pList->mOldDropHighlighter)) {
TQPainter painter(viewport());
style().tqdrawPrimitive(TQStyle::PE_FocusRect, &painter, m_pList->mOldDropHighlighter, colorGroup(),
TQStyle::Style_FocusAtBorder);
}
}
void tdesvnfilelist::cleanHighLighter()
{
if (m_pList->mOldDropHighlighter.isValid()) {
TQRect rect=m_pList->mOldDropHighlighter;
m_pList->mOldDropHighlighter=TQRect();
viewport()->repaint(rect, true);
}
}
/*!
\fn tdesvnfilelist::slotMergeRevisions()
*/
void tdesvnfilelist::slotMergeRevisions()
{
if (!isWorkingCopy()) return;
FileListViewItem*which= singleSelected();
if (!which) {
return;
}
bool force,dry,rec,irelated,useExternal;
Rangeinput_impl::revision_range range;
if (!MergeDlg_impl::getMergeRange(range,&force,&rec,&irelated,&dry,&useExternal,this,"merge_range")) {
return;
}
if (!useExternal) {
m_SvnWrapper->slotMergeWcRevisions(which->fullName(),range.first,range.second,rec,!irelated,force,dry);
} else {
m_SvnWrapper->slotMergeExternal(which->fullName(),which->fullName(),which->fullName(),range.first,range.second,
isWorkingCopy()?svn::Revision::WORKING:m_pList->m_remoteRevision,rec);
}
refreshItem(which);
refreshRecursive(which);
}
void tdesvnfilelist::slotMerge()
{
FileListViewItem*which= singleSelected();
TQString src1,src2,target;
if (isWorkingCopy()) {
if (m_pList->merge_Target.isEmpty()) {
target = which?which->fullName():baseUri();
} else {
target = m_pList->merge_Target;
}
src1 = m_pList->merge_Src1;
} else {
if (m_pList->merge_Src1.isEmpty()){
src1 = which?which->fullName():baseUri();
} else {
src1 = m_pList->merge_Src1;
}
target = m_pList->merge_Target;
}
src2 = m_pList->merge_Src2;
bool force,dry,rec,irelated,useExternal;
Rangeinput_impl::revision_range range;
MergeDlg_impl*ptr;
KDialogBase*dlg = createDialog(&ptr,TQString(i18n("Merge")),true,"merge_dialog",true);
if (!dlg) {
return;
}
dlg->setHelp("merging-items","tdesvn");
ptr->setDest(target);
ptr->setSrc1(src1);
ptr->setSrc2(src1);
if (dlg->exec()==TQDialog::Accepted) {
src1=ptr->Src1();
src2=ptr->Src2();
if (src2.isEmpty()) {
src2 = src1;
}
target = ptr->Dest();
m_pList->merge_Src2 = src2;
m_pList->merge_Src1 = src1;
m_pList->merge_Target = target;
force = ptr->force();
dry = ptr->dryrun();
rec = ptr->recursive();
irelated = ptr->ignorerelated();
useExternal = ptr->useExtern();
range = ptr->getRange();
if (!useExternal) {
m_SvnWrapper->slotMerge(src1,src2,target,range.first,range.second,
isWorkingCopy()?svn::Revision::WORKING:m_pList->m_remoteRevision,
rec,!irelated,force,dry);
} else {
m_SvnWrapper->slotMergeExternal(src1,src2,target,range.first,range.second,
isWorkingCopy()?svn::Revision::WORKING:m_pList->m_remoteRevision,rec);
}
if (isWorkingCopy()) {
// refreshItem(which);
// refreshRecursive(which);
refreshCurrentTree();
}
}
dlg->saveDialogSize(*(Kdesvnsettings::self()->config()),"merge_dialog",false);
delete dlg;
}
void tdesvnfilelist::slotDropped(TQDropEvent* event,TQListViewItem*item)
{
KURL::List urlList;
TQMap<TQString,TQString> metaData;
TQDropEvent::Action action = event->action();
if (!event || m_pList->intern_dropRunning||!KURLDrag::decode( event, urlList, metaData)||urlList.count()<1) {
return;
}
kdDebug()<<"slotDropped"<<endl;
TQString tdir;
if (item) {
FileListViewItem*which = static_cast<FileListViewItem*>(item);
clearSelection();
which->setSelected(true);
kapp->processEvents();
tdir = which->fullName();
} else {
tdir = baseUri();
}
if (event->source()!=viewport()) {
kdDebug()<<"Dropped from outside" << endl;
if (baseUri().length()==0) {
openURL(urlList[0]);
event->acceptAction();
return;
}
if (baseUri().length()>0 /*&& urlList[0].isLocalFile()*/) {
TQString path = urlList[0].path();
TQFileInfo fi(path);
if (!isWorkingCopy()) {
slotImportIntoDir(urlList[0],tdir,fi.isDir());
} else {
//m_pList->stopScan();
TDEIO::Job * job = 0L;
job = TDEIO::copy(urlList,tdir);
connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ),TQT_SLOT( slotCopyFinished( TDEIO::Job * ) ) );
dispDummy();
event->acceptAction();
return;
}
}
} else {
kdDebug()<<"Dropped from inside " << action << endl;
int root_x, root_y, win_x, win_y;
uint keybstate;
TQDropEvent::Action action = TQDropEvent::UserAction;
KeyState::keystate(&root_x,&root_y,&win_x,&win_y,&keybstate);
if (keybstate&TQt::ControlButton) {
kdDebug()<<"Control pressed" << endl;
action = TQDropEvent::Copy;
} else if (keybstate&TQt::ShiftButton) {
kdDebug()<<"Shift pressed" << endl;
action = TQDropEvent::Move;
}
/* converting urls to interal style */
TQString nProto;
if (isWorkingCopy()) {
nProto="";
} else {
nProto = svn::Url::transformProtokoll(urlList[0].protocol());
}
KURL::List::Iterator it = urlList.begin();
TQStringList l;
for (;it!=urlList.end();++it) {
l = TQStringList::split("?",(*it).prettyURL());
if (l.size()>1) {
(*it) = l[0];
} else if (isWorkingCopy())
{
(*it) = KURL::fromPathOrURL( (*it).path());
}
(*it).setProtocol(nProto);
kdDebug()<<"Dropped: "<<(*it)<<endl;
}
event->acceptAction();
m_pList->intern_dropRunning=true;
m_pList->intern_drops = urlList;
m_pList->intern_drop_target=tdir;
m_pList->intern_drop_action=action;
m_pList->intern_drop_pos=TQCursor::pos();
TQTimer::singleShot(0,this,TQT_SLOT(slotInternalDrop()));
// internalDrop(action,urlList,tdir);
}
}
void tdesvnfilelist::slotInternalDrop()
{
TQDropEvent::Action action = m_pList->intern_drop_action;
if (action==TQDropEvent::UserAction) {
TQPopupMenu popup;
popup.insertItem(SmallIconSet("goto"), i18n( "Move Here" ) + "\t" + KKey::modFlagLabel( KKey::SHIFT ), 2 );
popup.insertItem(SmallIconSet("editcopy"), i18n( "Copy Here" ) + "\t" + KKey::modFlagLabel( KKey::CTRL ), 1 );
popup.insertSeparator();
popup.insertItem(SmallIconSet("cancel"), i18n( "Cancel" ) + "\t" + KKey( TQt::Key_Escape ).toString(), 5);
int result = popup.exec(m_pList->intern_drop_pos);
switch (result) {
case 1 : action = TQDropEvent::Copy; break;
case 2 : action = TQDropEvent::Move; break;
default:
{
m_pList->intern_dropRunning=false;
return;
}
}
}
if (action==TQDropEvent::Move) {
m_SvnWrapper->makeMove(m_pList->intern_drops,m_pList->intern_drop_target,false);
} else {
m_SvnWrapper->makeCopy(m_pList->intern_drops,m_pList->intern_drop_target,svn::Revision::HEAD);
}
m_pList->intern_dropRunning=false;
refreshCurrentTree();
}
/*!
\fn tdesvnfilelist::slotRename()
*/
void tdesvnfilelist::slotRename()
{
copy_move(true);
}
void tdesvnfilelist::slotCopy()
{
copy_move(false);
}
void tdesvnfilelist::copy_move(bool move)
{
if (isWorkingCopy()&&singleSelected()==firstChild()) {
return;
}
bool ok, force;
FileListViewItem*which = singleSelected();
if (!which) return;
TQString nName = CopyMoveView_impl::getMoveCopyTo(&ok,&force,move,
which->fullName(),baseUri(),this,"move_name");
if (!ok) {
return;
}
if (move) {
m_SvnWrapper->makeMove(which->fullName(),nName,force);
} else {
m_SvnWrapper->makeCopy(which->fullName(),nName, isWorkingCopy()?svn::Revision::HEAD:m_pList->m_remoteRevision);
}
}
void tdesvnfilelist::slotCat()
{
FileListViewItem*k = singleSelected();
if (!k) return;
m_SvnWrapper->slotMakeCat(isWorkingCopy()?svn::Revision::HEAD:m_pList->m_remoteRevision, k->fullName(),k->text(0),
isWorkingCopy()?svn::Revision::HEAD:m_pList->m_remoteRevision,0);
}
/*!
\fn tdesvnfilelist::slotCopyFinished( TDEIO::Job *)
*/
void tdesvnfilelist::slotCopyFinished( TDEIO::Job * job)
{
if (m_pList->m_DirWatch) {
m_pList->m_DirWatch->startScan(false);
}
if (job) {
bool ok = true;
tqApp->exit_loop();
if (job->error()) {
job->showErrorDialog(this);
ok = false;
}
// always just connect a CopyJob here!!!!
if (ok) {
KURL::List lst = static_cast<TDEIO::CopyJob*>(job)->srcURLs();
KURL turl = static_cast<TDEIO::CopyJob*>(job)->destURL();
TQString base = turl.path(1);
KURL::List::iterator iter;
TQValueList<svn::Path> tmp;
for (iter=lst.begin();iter!=lst.end();++iter) {
tmp.push_back(svn::Path((base+(*iter).fileName(true))));
}
m_SvnWrapper->addItems(tmp,svn::DepthInfinity);
}
refreshCurrentTree();
}
}
/*!
\fn tdesvnfilelist::slotDelete()
*/
void tdesvnfilelist::slotDelete()
{
m_deletePerfect = true;
TQPtrList<FileListViewItem>*lst = allSelected();
if (lst->count()==0) {
KMessageBox::error(this,i18n("Nothing selected for delete"));
return;
}
FileListViewItemListIterator liter(*lst);
FileListViewItem*cur;
//m_pList->stopScan();
m_pList->m_fileTip->setItem(0);
TQValueList<svn::Path> items;
TQStringList displist;
KURL::List kioList;
while ((cur=liter.current())!=0){
++liter;
if (!cur->isRealVersioned()) {
KURL _uri; _uri.setPath(cur->fullName());
kioList.append(_uri);
} else {
items.push_back(cur->fullName());
}
displist.append(cur->fullName());
}
int answer = KMessageBox::questionYesNoList(this,i18n("Really delete these entries?"),displist,i18n("Delete from repository"));
if (answer!=KMessageBox::Yes) {
return;
}
if (kioList.count()>0) {
TDEIO::Job*aJob = TDEIO::del(kioList);
connect(aJob,TQT_SIGNAL(result (TDEIO::Job *)),this,TQT_SLOT(slotDeleteFinished(TDEIO::Job*)));
dispDummy();
}
if (m_deletePerfect && items.size()>0) {
m_SvnWrapper->makeDelete(items);
}
refreshCurrentTree();
//m_pList->startScan();
}
/*!
\fn tdesvnfilelist::slotDeleteFinished(TDEIO::Job*)
*/
void tdesvnfilelist::slotDeleteFinished(TDEIO::Job*job)
{
if (job) {
tqApp->exit_loop();
if (job->error()) {
job->showErrorDialog(this);
m_deletePerfect = false;
}
}
}
/*!
\fn tdesvnfilelist::dispDummy()
*/
void tdesvnfilelist::dispDummy()
{
// wait for job
TQLabel dummy(this,0,WStyle_NoBorder|WShowModal);
TQSize csize = size();
dummy.setText(i18n("Please wait until job is finished"));
dummy.resize(dummy.minimumSizeHint());
if (dummy.width()<=width()&&dummy.height()<=height()) {
dummy.move(csize.width()/2-dummy.width()/2,csize.height()/2-dummy.height()/2);
}
dummy.show();
tqApp->enter_loop();
dummy.hide();
}
/*!
\fn tdesvnfilelist::slotLock()
*/
void tdesvnfilelist::slotLock()
{
TQPtrList<FileListViewItem>*lst = allSelected();
FileListViewItemListIterator liter(*lst);
FileListViewItem*cur;
if (lst->count()==0) {
KMessageBox::error(this,i18n("Nothing selected for lock"));
return;
}
KDialogBase*dlg;
Logmsg_impl*ptr;
dlg = createDialog(&ptr,TQString(i18n("Lock message")),true,"locking_log_msg");
if (!dlg) return;
ptr->initHistory();
ptr->hideDepth(true);
TQCheckBox*_stealLock = new TQCheckBox("",ptr,"create_dir_checkbox");
_stealLock->setText(i18n("Steal lock?"));
ptr->addItemWidget(_stealLock);
ptr->m_keepLocksButton->hide();
if (dlg->exec()!=TQDialog::Accepted) {
ptr->saveHistory(true);
delete dlg;
return;
}
dlg->saveDialogSize(*(Kdesvnsettings::self()->config()),"locking_log_msg",false);
TQString logMessage = ptr->getMessage();
bool steal = _stealLock->isChecked();
ptr->saveHistory(false);
TQStringList displist;
while ((cur=liter.current())!=0){
++liter;
displist.append(cur->fullName());
}
m_SvnWrapper->makeLock(displist,logMessage,steal);
refreshCurrentTree();
}
/*!
\fn tdesvnfilelist::slotUnlock()
*/
void tdesvnfilelist::slotUnlock()
{
TQPtrList<FileListViewItem>*lst = allSelected();
FileListViewItemListIterator liter(*lst);
FileListViewItem*cur;
if (lst->count()==0) {
KMessageBox::error(this,i18n("Nothing selected for unlock"));
return;
}
int res = KMessageBox::questionYesNoCancel(this,i18n("Break lock or ignore missing locks?"),i18n("Unlocking items"));
if (res == KMessageBox::Cancel) {
return;
}
bool breakit = res==KMessageBox::Yes;
TQStringList displist;
while ((cur=liter.current())!=0){
++liter;
displist.append(cur->fullName());
}
m_SvnWrapper->makeUnlock(displist,breakit);
refreshCurrentTree();
}
/*!
\fn tdesvnfilelist::slotIgnore()
*/
void tdesvnfilelist::slotIgnore()
{
SvnItem*item = singleSelected();
if (!item || item->isRealVersioned()) return;
if (m_SvnWrapper->makeIgnoreEntry(item,item->isIgnored())) {
refreshCurrentTree();
}
}
/*!
\fn tdesvnfilelist::slotBlame()
*/
void tdesvnfilelist::slotBlame()
{
SvnItem*k = singleSelected();
if (!k) return;
svn::Revision start(svn::Revision::START);
svn::Revision end(svn::Revision::HEAD);
m_SvnWrapper->makeBlame(start,end,k);
}
/*!
\fn tdesvnfilelist::slotRangeBlame()
*/
void tdesvnfilelist::slotRangeBlame()
{
SvnItem*k = singleSelected();
if (!k) return;
Rangeinput_impl*rdlg;
KDialogBase*dlg = createDialog(&rdlg,TQString(i18n("Revisions")),true,"revisions_dlg");
if (!dlg) {
return;
}
if (dlg->exec()==TQDialog::Accepted) {
Rangeinput_impl::revision_range r = rdlg->getRange();
m_SvnWrapper->makeBlame(r.first,r.second,k);
}
dlg->saveDialogSize(*(Kdesvnsettings::self()->config()),"revisions_dlg",false);
delete dlg;
}
void tdesvnfilelist::slotSimpleBaseDiff()
{
FileListViewItem*kitem = singleSelected();
if (isWorkingCopy())
{
chdir(baseUri().local8Bit());
}
TQString what;
if (!kitem) {
what==".";
} else {
what = relativePath(kitem);
}
// only possible on working copies - so we may say this values
m_SvnWrapper->makeDiff(what,svn::Revision::BASE,svn::Revision::WORKING,svn::Revision::UNDEFINED,kitem?kitem->isDir():true);
}
void tdesvnfilelist::slotSimpleHeadDiff()
{
FileListViewItem*kitem = singleSelected();
TQString what;
if (isWorkingCopy())
{
chdir(baseUri().local8Bit());
}
if (!kitem) {
what=".";
}else{
what = relativePath(kitem);
}
// only possible on working copies - so we may say this values
m_SvnWrapper->makeDiff(what,svn::Revision::WORKING,svn::Revision::HEAD,svn::Revision::UNDEFINED,kitem?kitem->isDir():true);
}
void tdesvnfilelist::slotDisplayLastDiff()
{
FileListViewItem*kitem = singleSelected();
TQString what;
if (isWorkingCopy())
{
chdir(baseUri().local8Bit());
}
svn::Revision end = svn::Revision::PREV;
if (!kitem) {
if (isWorkingCopy()) {
TQListViewItem*fi = firstChild();
kitem = static_cast<FileListViewItem*>(fi);
if (!kitem) {
return;
}
what = relativePath(kitem);
} else {
what=baseUri();
}
}else{
what = relativePath(kitem);
}
svn::Revision start;
svn::InfoEntry inf;
if (!kitem) {
// it has to have an item when in working copy, so we know we are in repository view.
if (!m_SvnWrapper->singleInfo(what,m_pList->m_remoteRevision,inf)) {
return;
}
start = inf.cmtRev();
} else {
start = kitem->cmtRev();
}
if (!isWorkingCopy()) {
if (!m_SvnWrapper->singleInfo(what,start.revnum()-1,inf)) {
return;
}
end = inf.cmtRev();
}
m_SvnWrapper->makeDiff(what,end,what,start,realWidget());
}
void tdesvnfilelist::slotDiffPathes()
{
TQPtrList<FileListViewItem>*lst = allSelected();
if (lst->count()!=2 || !uniqueTypeSelected()) {
return;
}
m_pList->m_fileTip->setItem(0);
FileListViewItem*k1,*k2;
k1 = lst->at(0);
k2 = lst->at(1);
TQString w1,w2;
svn::Revision r1;
if (isWorkingCopy()) {
chdir(baseUri().local8Bit());
w1 = relativePath(k1);
w2 = relativePath(k2);
r1 = svn::Revision::WORKING;
} else {
w1 = k1->fullName();
w2 = k2->fullName();
r1 = m_pList->m_remoteRevision;
}
m_SvnWrapper->makeDiff(w1,r1,w2,r1);
}
/*!
\fn tdesvnfilelist::slotMkdir()
*/
void tdesvnfilelist::slotMkdir()
{
SvnItem*k = singleSelected();
TQString parentDir;
if (k) {
if (!k->isDir()) {
KMessageBox::sorry(0,i18n("May not make subdirs of a file"));
return;
}
parentDir=k->fullName();
} else {
parentDir=baseUri();
}
TQString ex = m_SvnWrapper->makeMkdir(parentDir);
if (!ex.isEmpty()) {
slotDirAdded(ex,static_cast<FileListViewItem*>(k));
}
}
void tdesvnfilelist::slotMkBaseDirs()
{
bool isopen = baseUri().length()>0;
if (!isopen) {
return;
}
TQString parentDir=baseUri();
TQStringList targets;
targets.append(parentDir+"/trunk");
targets.append(parentDir+"/branches");
targets.append(parentDir+"/tags");
TQString msg = i18n("Automatic generated base layout by tdesvn");
isopen = m_SvnWrapper->makeMkdir(targets,msg);
if (isopen) {
slotDirAdded(targets[0],0);
// slotDirAdded(targets[1],0);
// slotDirAdded(targets[2],0);
}
}
/*!
\fn tdesvnfilelist::slotDiffRevisions()
*/
void tdesvnfilelist::slotDiffRevisions()
{
SvnItem*k = singleSelected();
TQString what;
if (isWorkingCopy())
{
chdir(baseUri().local8Bit());
}
if (!k) {
what=(isWorkingCopy()?".":baseUri());
}else{
what = relativePath(k);
}
Rangeinput_impl*rdlg;
KDialogBase*dlg = createDialog(&rdlg,TQString(i18n("Revisions")),true,"revisions_dlg");
if (!dlg) {
return;
}
if (dlg->exec()==TQDialog::Accepted) {
Rangeinput_impl::revision_range r = rdlg->getRange();
svn::Revision _peg=(isWorkingCopy()?svn::Revision::WORKING:remoteRevision());
m_SvnWrapper->makeDiff(what,r.first,r.second,_peg,k?k->isDir():true);
}
dlg->saveDialogSize(*(Kdesvnsettings::self()->config()),"revisions_dlg",false);
delete dlg;
}
void tdesvnfilelist::slotSelectBrowsingRevision()
{
if (isWorkingCopy()) return;
Rangeinput_impl*rdlg;
KDialogBase*dlg = createDialog(&rdlg,TQString(i18n("Revisions")),true,"revisions_dlg");
if (!dlg) {
return;
}
rdlg->setStartOnly(true);
if (dlg->exec()==TQDialog::Accepted) {
Rangeinput_impl::revision_range r = rdlg->getRange();
m_pList->m_remoteRevision= r.first;
if (childCount()==0) {
checkDirs(baseUri(),0);
} else {
refreshCurrentTree();
}
}
dlg->saveDialogSize(*(Kdesvnsettings::self()->config()),"revisions_dlg",false);
delete dlg;
}
/*!
\fn tdesvnfilelist::slotRevisionCat()
*/
void tdesvnfilelist::slotRevisionCat()
{
SvnItem*k = singleSelected();
if (!k) return;
Rangeinput_impl*rdlg;
KDialogBase*dlg = createDialog(&rdlg,TQString(i18n("Revisions")),true,"revisions_dlg");
if (!dlg) {
return;
}
rdlg->setStartOnly(true);
if (dlg->exec()==TQDialog::Accepted) {
Rangeinput_impl::revision_range r = rdlg->getRange();
m_SvnWrapper->slotMakeCat(r.first, k->fullName(),k->shortName(),r.first,0);
}
dlg->saveDialogSize(*(Kdesvnsettings::self()->config()),"revisions_dlg",false);
delete dlg;
}
/*!
\fn tdesvnfilelist::refreshItem(FileListViewItem*)
*/
bool tdesvnfilelist::refreshItem(FileListViewItem*item)
{
if (!item) {
return false;
}
try {
item->setStat(svnclient()->singleStatus(item->fullName(),false,m_pList->m_remoteRevision));
} catch (const svn::ClientException&e) {
item->setStat(new svn::Status());
return false;
}
return true;
}
/*!
\fn tdesvnfilelist::slotCheckUpdates()
*/
void tdesvnfilelist::slotCheckUpdates()
{
m_SvnWrapper->createUpdateCache(baseUri());
}
/*!
\fn tdesvnfilelist::reinitItems(FileListViewItem*_item = 0)
*/
void tdesvnfilelist::reinitItems(FileListViewItem*_item)
{
FileListViewItem*item;
if (_item) {
item = _item;
} else {
item = static_cast<FileListViewItem*>(firstChild());
}
if (!item) {
return;
}
item->init();
if (item->childCount()==0 && item->isOpen()) {
m_Dirsread[item->fullName()]=false;;
setEnabled(false);
slotItemRead(item);
setEnabled(true);
} else {
item = static_cast<FileListViewItem*>(item->firstChild());
while(item) {
reinitItems(item);
item = static_cast<FileListViewItem*>(item->nextSibling());
}
}
}
/*!
\fn tdesvnfilelist::slotInfo()
*/
void tdesvnfilelist::slotInfo()
{
TQPtrList<SvnItem> lst;
SelectionList(&lst);
svn::Revision rev(isWorkingCopy()?svn::Revision::UNDEFINED:m_pList->m_remoteRevision);
if (!isWorkingCopy()) {
rev = m_pList->m_remoteRevision;
}
if (lst.count()==0) {
if (!isWorkingCopy()) {
m_SvnWrapper->makeInfo(baseUri(),rev,svn::Revision::UNDEFINED,Kdesvnsettings::info_recursive());
} else {
lst.append(SelectedOrMain());
}
}
if (lst.count()>0) {
m_SvnWrapper->makeInfo(lst,rev,rev,Kdesvnsettings::info_recursive());
}
}
/*!
\fn tdesvnfilelist::slotDirItemCreated(const TQString&)
*/
void tdesvnfilelist::slotDirItemCreated(const TQString&what)
{
m_pList->stopDirTimer();
m_pList->dirItems[what]='C';
kdDebug()<<"slotDirItemCreated "<<what<<endl;
m_pList->startDirTimer();
}
void tdesvnfilelist::updateParents(FileListViewItem*item)
{
if (!item || !item->parent()) return;
FileListViewItem*it = static_cast<FileListViewItem*>(item->parent());
it->update();
updateParents(it);
}
/*!
\fn tdesvnfilelist::slotDirItemDirty(const TQString&)
*/
void tdesvnfilelist::slotDirItemDirty(const TQString&what)
{
m_pList->stopDirTimer();
m_pList->dirItems[what]='M';
m_pList->startDirTimer();
}
void tdesvnfilelist::_propListTimeout()
{
dispProperties(false);
}
void tdesvnfilelist::slotDisplayProperties()
{
dispProperties(true);
}
void tdesvnfilelist::dispProperties(bool force)
{
CursorStack a(TQt::BusyCursor);
bool cache_Only = (!force && isNetworked() && !Kdesvnsettings::properties_on_remote_items());
svn::PathPropertiesMapListPtr pm;
SvnItem*k = singleSelected();
if (!k || !k->isRealVersioned()) {
emit sigProplist(svn::PathPropertiesMapListPtr(),false,TQString(""));
return;
}
kdDebug()<<"Cacheonly: "<<cache_Only<<endl;
svn::Revision rev(isWorkingCopy()?svn::Revision::WORKING:m_pList->m_remoteRevision);
pm =m_SvnWrapper->propList(k->fullName(),rev,cache_Only);
emit sigProplist(pm,isWorkingCopy(),k->fullName());
}
void tdesvnfilelist::_dirwatchTimeout()
{
kdDebug()<<"dirtimer"<<endl;
TQMap<TQString,TQChar>::Iterator it;
m_pList->m_fileTip->setItem(0);
viewport()->setUpdatesEnabled(false);
bool repaintit=false;
for (it=m_pList->dirItems.begin();it!=m_pList->dirItems.end();++it)
{
TQString what = it.key();
TQChar c = it.data();
FileListViewItem*item = findEntryItem(what);
if (!item) {
m_pList->m_DirWatch->removeDir(what);
m_pList->m_DirWatch->removeFile(what);
m_SvnWrapper->deleteFromModifiedCache(what);
continue;
}
if (c == 'M') {
if (!item->isNormal() && item->isRealVersioned()) {
m_SvnWrapper->addModifiedCache(item->stat());
} else {
m_SvnWrapper->deleteFromModifiedCache(what);
}
if (item->isDir()) {
if (item->isRealVersioned()) {
repaintit = refreshRecursive(item,false);
} else {
TQListViewItem *_s;
while ( (_s=item->firstChild()))
{
delete _s;
}
checkUnversionedDirs(item);
}
}
updateParents(static_cast<FileListViewItem*>(item->parent()));
} else if (c=='D') {
if (item->isDir()) {
m_pList->m_DirWatch->removeDir(what);
} else {
m_pList->m_DirWatch->removeFile(what);
}
if (item->isDeleted()) {
m_SvnWrapper->addModifiedCache(item->stat());
} else if (!item->isMissing()) {
TQFileInfo fi(what);
if (!fi.exists()) {
FileListViewItem*p = static_cast<FileListViewItem*>(item->parent());
delete item;
repaintit=true;
item = 0;
if (p && p->isVersioned()) {
p->update();
updateParents(p);
}
}
}
}
#if 0
when add dirItemDirty is send for folder above so no need for checking add-flag.
else {
kdDebug()<<"Entry added: "<<what << endl;
}
#endif
if (item) {
refreshItem(item);
}
}
m_pList->dirItems.clear();
viewport()->setUpdatesEnabled(true);
if (repaintit) {
// viewport()->repaint();
}
}
/*!
\fn tdesvnfilelist::slotDirItemDeleted(const TQString&)
*/
void tdesvnfilelist::slotDirItemDeleted(const TQString&what)
{
m_pList->stopDirTimer();
m_pList->m_fileTip->setItem(0);
TQMap<TQString,TQChar>::Iterator it = m_pList->dirItems.find(what);
if (it!=m_pList->dirItems.end() && m_pList->dirItems[what]=='A') {
m_pList->dirItems.erase(it);
} else {
m_pList->dirItems[what]='D';
}
m_pList->startDirTimer();
}
void tdesvnfilelist::gotPreview( const KFileItem*, const TQPixmap&)
{
#if 0
FileListViewItem*which = findEntryItem(item->localPath());
if (which) {
which->setPreviewPix(pixmap);
}
// m_previewJob = 0;
// if (m_svnitem || item != m_svnitem->fileItem()) return;
// m_iconLabel -> setPixmap(pixmap);
#endif
}
void tdesvnfilelist::gotPreviewResult()
{
// m_previewJob = 0;
}
FileListViewItem* tdesvnfilelist::findEntryItem(const TQString&what,FileListViewItem*startAt)
{
if (!startAt && !what.startsWith(baseUri())) return 0;
TQString _what = what;
FileListViewItem*_s,*_temp;
if (!startAt) {
while (_what.endsWith("/")) {
_what.truncate(_what.length()-1);
}
_s = static_cast<FileListViewItem*>(firstChild());
} else {
_s = static_cast<FileListViewItem*>(startAt->firstChild());
}
_temp = 0;
while (_s) {
if (_s->fullName()==_what) {
return _s;
}
if (_what.startsWith(_s->fullName())) {
_temp = findEntryItem(_what,_s);
if (_temp) {
return _temp;
}
}
_s = static_cast<FileListViewItem*>(_s->nextSibling());
}
return 0;
}
/*!
\fn tdesvnfilelist::contentsMouseMoveEvent( TQMouseEvent *e )
*/
void tdesvnfilelist::contentsMouseMoveEvent( TQMouseEvent *e )
{
if (!m_pList->mousePressed)
{
if (Kdesvnsettings::display_file_tips()) {
TQPoint vp = contentsToViewport( e->pos() );
FileListViewItem*item = isExecuteArea( vp ) ? static_cast<FileListViewItem*>(itemAt( vp )) : 0L;
if (item) {
vp.setY( itemRect( item ).y() );
TQRect rect( viewportToContents( vp ), TQSize(20, item->height()) );
m_pList->m_fileTip->setItem( static_cast<SvnItem*>(item), rect, item->pixmap(0));
m_pList->m_fileTip->setPreview(TDEGlobalSettings::showFilePreview(item->fullName())/*&&isWorkingCopy()*/
&&Kdesvnsettings::display_previews_in_file_tips());
setShowToolTips(false);
} else {
m_pList->m_fileTip->setItem(0);
setShowToolTips(true);
}
} else {
m_pList->m_fileTip->setItem(0);
setShowToolTips(true);
}
}
else
{
if (( m_pList->presspos - e->pos() ).manhattanLength() > TQApplication::startDragDistance())
{
m_pList->m_fileTip->setItem(0);
m_pList->mousePressed=false;
//beginDrag();
}
}
KListView::contentsMouseMoveEvent( e );
}
void tdesvnfilelist::contentsMousePressEvent(TQMouseEvent*e)
{
KListView::contentsMousePressEvent(e);
m_pList->m_fileTip->setItem(0);
TQPoint p(contentsToViewport( e->pos()));
TQListViewItem *i = itemAt( p );
// this is from qt the example - hopefully I got my problems with drag&drop fixed.
if ( i ) {
// if the user clicked into the root decoration of the item, don't try to start a drag!
if ( p.x() > header()->cellPos( header()->mapToActual( 0 ) ) +
treeStepSize() * ( i->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() ||
p.x() < header()->cellPos( header()->mapToActual( 0 ) ) )
{
m_pList->presspos = e->pos();
m_pList->mousePressed = true;
}
}
}
void tdesvnfilelist::contentsMouseReleaseEvent(TQMouseEvent*e)
{
KListView::contentsMouseReleaseEvent(e);
m_pList->mousePressed = false;
}
/*!
\fn tdesvnfilelist::contentsWheelEvent( TQWheelEvent * e )
*/
void tdesvnfilelist::contentsWheelEvent( TQWheelEvent * e )
{
// when scrolling with mousewheel, stop possible pending filetip
m_pList->m_fileTip->setItem(0);
KListView::contentsWheelEvent( e );
}
void tdesvnfilelist::leaveEvent(TQEvent*e)
{
m_pList->m_fileTip->setItem( 0 );
KListView::leaveEvent( e );
}
void tdesvnfilelist::slotSettingsChanged()
{
m_pList->m_fileTip->setOptions(!isNetworked()&&Kdesvnsettings::display_file_tips()&&
TQToolTip::isGloballyEnabled(),true,6);
if (m_pList->reReadSettings()) {
refreshCurrentTree();
} else {
viewport()->repaint();
}
enableActions();
sort();
if (m_SvnWrapper && !m_SvnWrapper->doNetworking()) {
m_SvnWrapper->stopFillCache();
}
}
/*!
\fn tdesvnfilelist::slotRelocate()
*/
void tdesvnfilelist::slotRelocate()
{
if (!isWorkingCopy()) return;
SvnItem*k = SelectedOrMain();
if (!k) {
KMessageBox::error(0,i18n("Error getting entry to relocate"));
return;
}
TQString path,fromUrl;
path = k->fullName();
fromUrl = k->Url();
CheckoutInfo_impl*ptr;
KDialogBase * dlg = createDialog(&ptr,i18n("Relocate path %1").arg(path),true,"relocate_dlg");
if (dlg) {
ptr->setStartUrl(fromUrl);
ptr->disableAppend(true);
ptr->disableTargetDir(true);
ptr->disableRange(true);
ptr->disableOpen(true);
ptr->disableExternals(true);
ptr->hideDepth(true,true);
bool done = false;
dlg->resize(dlg->configDialogSize(*(Kdesvnsettings::self()->config()),"relocate_dlg"));
if (dlg->exec()==TQDialog::Accepted) {
done = m_SvnWrapper->makeRelocate(fromUrl,ptr->reposURL(),path,ptr->overwrite());
}
dlg->saveDialogSize(*(Kdesvnsettings::self()->config()),"relocate_dlg",false);
delete dlg;
if (!done) return;
}
refreshItem(k->fItem());
}
void tdesvnfilelist::checkUnversionedDirs( FileListViewItem * _parent )
{
TQDir d;
if (_parent)
d.setPath(_parent->fullName()); //FIXME: this one is not reliable, what if _parent == 0??
// else
// d.setPath(this->firstChild()->fullName());
d.setFilter( TQDir::Files | TQDir::Dirs );
const TQFileInfoList *list = d.entryInfoList();
if (!list) {
return;
}
TQFileInfoListIterator nonversioned_it( *list );
TQFileInfo *fi;
svn::StatusEntries nonversioned_list;
// FIXME: create a dlist and feed to insertDirs, mean while .. we are copying insertDirs since we weren't able to set svn_node_kind into appropriate value
while ( (fi = nonversioned_it.current()) != 0 ) {
if ((fi->fileName()!=".") && (fi->fileName()!="..")) {
// trying to set entry->kind
// svn_wc_status2_t wc_stat;
// svn_wc_entry_t entry;
// char *temp;
// strcpy(temp, fi->fileName());
// entry.name = temp;
//
// wc_stat.entry = &entry;
// if (fi->isDir())
// entry.kind = svn_node_dir;
// else
// entry.kind = svn_node_file;
//
// svn::Status stat(fi->fileName(), &wc_stat);
svn::StatusPtr stat(new svn::Status(fi->absFilePath()));
// start copying insertDirs
FileListViewItem * item;
if (!_parent) {
item = new FileListViewItem(this, stat);
kdDebug()<< "creating new FileListViewitem " + item->fullName() << endl;
} else {
item = new FileListViewItem(this,_parent, stat);
kdDebug()<< "creating new FileListViewitem (with parent) " + item->fullName() << endl;
}
if (fi->isDir()) {
m_Dirsread[item->fullName()]=false;
item->setDropEnabled(true);
if (isWorkingCopy()) {
m_pList->m_DirWatch->addDir(item->fullName());
}
kdDebug()<< "Watching folder: " + item->fullName() << endl;
} else if (isWorkingCopy()) {
m_pList->m_DirWatch->addFile(item->fullName());
kdDebug()<< "Watching file: " + item->fullName() << endl;
}
// end of copying insertDirs
nonversioned_list.append(stat);
kdDebug() << "creating new FileListViewItem from TQDir entry: " << fi->fileName() << endl;
}
++nonversioned_it;
}
// uncomment this if you've ben able to set svn_node_kind (see above)
//this->insertDirs(_parent, nonversioned_list);
}
void tdesvnfilelist::rescanIconsRec(FileListViewItem*startAt,bool checkNewer,bool no_update)
{
FileListViewItem*_s;
if (!startAt) {
_s = static_cast<FileListViewItem*>(firstChild());
} else {
_s = static_cast<FileListViewItem*>(startAt->firstChild());
}
if (!_s) {
return;
}
svn::SharedPointer<svn::Status> d;
while (_s) {
//_s->makePixmap();
if (!no_update) {
if (m_SvnWrapper->getUpdated(_s->stat()->path(),d) && d) {
_s->updateStatus(d);
} else {
_s->update();
}
}
rescanIconsRec(_s,checkNewer,no_update);
if (checkNewer && _s->isDir() && _s->isOpen()) {
svn::StatusEntries target;
m_SvnWrapper->getaddedItems(_s->stat()->path(),target);
insertDirs(_s,target);
}
_s = static_cast<FileListViewItem*>(_s->nextSibling());
}
}
void tdesvnfilelist::slotRescanIcons(bool checkNewer)
{
rescanIconsRec(0L,checkNewer);
}
/*!
\fn tdesvnfilelist::slotCheckNewItems()
*/
void tdesvnfilelist::slotCheckNewItems()
{
if (!isWorkingCopy()) {
KMessageBox::sorry(0,i18n("Only in working copy possible."),i18n("Error"));
return;
}
if (allSelected()->count()>1) {
KMessageBox::sorry(0,i18n("Only on single folder possible"),i18n("Error"));
return;
}
SvnItem*w = SelectedOrMain();
if (!w) {
KMessageBox::sorry(0,i18n("Sorry - internal error!"),i18n("Error"));
return;
}
m_SvnWrapper->checkAddItems(w->fullName(),true);
}
/*!
\fn tdesvnfilelist::slotMakeRangeLog()
*/
void tdesvnfilelist::slotMakeRangeLog()
{
TQString what;
SvnItem*k = SelectedOrMain();
if (k) {
what = k->fullName();
} else if (!isWorkingCopy() && allSelected()->count()==0){
what = baseUri();
} else {
return;
}
Rangeinput_impl*rdlg;
KDialogBase*dlg = createDialog(&rdlg,TQString(i18n("Revisions")),true,"revisions_dlg");
if (!dlg) {
return;
}
bool list = Kdesvnsettings::self()->log_always_list_changed_files();
int i = dlg->exec();
if (i==TQDialog::Accepted) {
Rangeinput_impl::revision_range r = rdlg->getRange();
m_SvnWrapper->makeLog(r.first,r.second,(isWorkingCopy()?svn::Revision::UNDEFINED:m_pList->m_remoteRevision), what,list,0);
}
dlg->saveDialogSize(*(Kdesvnsettings::self()->config()),"revisions_dlg",false);
}
void tdesvnfilelist::slotMakeTree()
{
TQString what;
SvnItem*k = SelectedOrMain();
if (k) {
what = k->fullName();
} else if (!isWorkingCopy() && allSelected()->count()==0){
what = baseUri();
} else {
return;
}
svn::Revision rev(isWorkingCopy()?svn::Revision::WORKING:m_pList->m_remoteRevision);
m_SvnWrapper->makeTree(what,rev);
}
void tdesvnfilelist::slotMakePartTree()
{
TQString what;
SvnItem*k = SelectedOrMain();
if (k) {
what = k->fullName();
} else if (!isWorkingCopy() && allSelected()->count()==0){
what = baseUri();
} else {
return;
}
Rangeinput_impl*rdlg;
KDialogBase*dlg = createDialog(&rdlg,TQString(i18n("Revisions")),true,"revisions_dlg");
if (!dlg) {
return;
}
int i = dlg->exec();
Rangeinput_impl::revision_range r;
if (i==TQDialog::Accepted) {
r = rdlg->getRange();
}
dlg->saveDialogSize(*(Kdesvnsettings::self()->config()),"revisions_dlg",false);
if (i==TQDialog::Accepted) {
svn::Revision rev(isWorkingCopy()?svn::Revision::UNDEFINED:m_pList->m_remoteRevision);
m_SvnWrapper->makeTree(what,rev,r.first,r.second);
}
}
/*!
\fn tdesvnfilelist::slotMakeLog()
*/
void tdesvnfilelist::slotMakeLog()
{
TQString what;
SvnItem*k = SelectedOrMain();
if (k) {
what = k->fullName();
} else if (!isWorkingCopy() && allSelected()->count()==0){
what = baseUri();
} else {
return;
}
// yes! so if we have a limit, the limit counts from HEAD
// not from START
svn::Revision start(svn::Revision::HEAD);
if (!isWorkingCopy()) {
start=m_pList->m_remoteRevision;
}
svn::Revision end(svn::Revision::START);
bool list = Kdesvnsettings::self()->log_always_list_changed_files();
int l = Kdesvnsettings::self()->maximum_displayed_logs();
m_SvnWrapper->makeLog(start,end,(isWorkingCopy()?svn::Revision::UNDEFINED:m_pList->m_remoteRevision),what,list,l);
}
const svn::Revision& tdesvnfilelist::remoteRevision()const
{
return m_pList->m_remoteRevision;
}
/*!
\fn tdesvnfilelist::slotOpenWith()
*/
void tdesvnfilelist::slotOpenWith()
{
FileListViewItem* which = singleSelected();
if (!which||which->isDir()) {
return;
}
svn::Revision rev(isWorkingCopy()?svn::Revision::UNDEFINED:m_pList->m_remoteRevision);
KURL::List lst;
lst.append(which->kdeName(rev));
KRun::displayOpenWithDialog(lst);
}
void tdesvnfilelist::slotUnfoldTree()
{
StopSimpleDlg sdlg(0,0,i18n("Unfold tree"),i18n("Unfold all folder"));
connect(this,TQT_SIGNAL(sigListError()),
&sdlg,TQT_SLOT(makeCancel()));
TQListViewItemIterator it(this);
TQTime t;t.start();
setUpdatesEnabled(false);
{
WidgetBlockStack a(this);
while (TQListViewItem* item = it.current())
{
if (item->isExpandable()) {
if (sdlg.isCanceld()) {
m_SvnWrapper->slotCancel(true);
break;
}
if (t.elapsed()>=200) {
sdlg.slotTick();
kapp->processEvents(20);
t.restart();
}
((FileListViewItem*)item)->setOpenNoBlock(true);
}
++it;
}
}
setFocus();
setUpdatesEnabled(true);
viewport()->repaint();
repaint();
m_SvnWrapper->slotCancel(false);
}
void tdesvnfilelist::slotFoldTree()
{
TQListViewItemIterator it(this);
while (TQListViewItem* item = it.current())
{
// don't close the top level directory
if (item->isExpandable() && item->parent())
item->setOpen(false);
++it;
}
}
/*!
\fn tdesvnfilelist::uniqueSelected()
*/
bool tdesvnfilelist::uniqueTypeSelected()
{
FileListViewItemList*ls = allSelected();
FileListViewItemListIterator it(*ls);
FileListViewItem*cur=it.current();
if (!cur) {
return false;
}
bool dir = cur->isDir();
while ( (cur=it.current())!=0) {
++it;
if (cur->isDir()!=dir) {
return false;
}
}
return true;
}
void tdesvnfilelist::slotChangeProperties(const svn::PropertiesMap&pm,const TQValueList<TQString>&dellist,const TQString&path)
{
m_SvnWrapper->changeProperties(pm,dellist,path);
FileListViewItem* which = singleSelected();
kdDebug()<<(which?which->fullName():"nix") << " -> " << path<<endl;
if (which && which->fullName()==path) {
which->refreshStatus();
refreshCurrent(which);
_propListTimeout();
}
}
void tdesvnfilelist::slotUpdateLogCache()
{
if (baseUri().length()>0 && m_SvnWrapper->doNetworking()) {
KAction*temp = filesActions()->action("update_log_cache");
if (!m_SvnWrapper->threadRunning(SvnActions::fillcachethread)) {
m_SvnWrapper->startFillCache(baseUri());
if (temp) {
temp->setText(i18n("Stop updating the logcache"));
}
} else {
m_SvnWrapper->stopFillCache();
if (temp) {
temp->setText(i18n("Update log cache"));
}
}
}
}
#include "tdesvnfilelist.moc"