diff options
Diffstat (limited to 'src/svnfrontend/tdesvnfilelist.cpp')
-rw-r--r-- | src/svnfrontend/tdesvnfilelist.cpp | 3160 |
1 files changed, 3160 insertions, 0 deletions
diff --git a/src/svnfrontend/tdesvnfilelist.cpp b/src/svnfrontend/tdesvnfilelist.cpp new file mode 100644 index 0000000..976d3c1 --- /dev/null +++ b/src/svnfrontend/tdesvnfilelist.cpp @@ -0,0 +1,3160 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 by Rajko Albrecht * + * [email protected] * + * * + * 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 "src/settings/tdesvnsettings.h" +#include "src/svnqt/revision.hpp" +#include "src/svnqt/dirent.hpp" +#include "src/svnqt/client.hpp" +#include "src/svnqt/status.hpp" +#include "src/svnqt/url.hpp" +#include "helpers/sshagent.h" +#include "helpers/sub2qt.h" +#include "fronthelpers/cursorstack.h" +#include "fronthelpers/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(sigCachetqStatus(TQ_LONG,TQ_LONG)),this,TQT_SIGNAL(sigCachetqStatus(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->maketqStatus(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::tqStatus 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()->tqrepaint(); + } + 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()->tqrepaint(); + 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->refreshtqStatus(); + } + 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()->singletqStatus(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(KApplication::activeModalWidget()),what,i18n("SVN Error")); +} + + +/*! + \fn tdesvnfilelist::slotNotifyMessage(const TQString&) + */ +void tdesvnfilelist::slotNotifyMessage(const TQString&what) +{ + emit sigLogMessage(what); + kapp->tqprocessEvents(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(KApplication::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").tqarg(feditor).tqarg(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->refreshtqStatus(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->refreshtqStatus(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(KApplication::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()->tqrepaint(); + return; + } else { + refreshRecursive(item); + } + } else { + refreshRecursive(0); + } + if (isWorkingCopy()) { + m_SvnWrapper->createModifiedCache(baseUri()); + } + kdDebug()<<"Refresh time: "<<t.elapsed()<<" ms"<<endl; + setUpdatesEnabled(true); + viewport()->tqrepaint(); + 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()->tqrepaint(); +} + +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->maketqStatus(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->updatetqStatus(*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()); + } + 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()->tqrepaint(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()); + tqstyle().tqdrawPrimitive(TQStyle::PE_FocusRect, &painter, m_pList->mOldDropHighlighter, tqcolorGroup(), + TQStyle::Style_FocusAtBorder); + } +} + +void tdesvnfilelist::cleanHighLighter() +{ + if (m_pList->mOldDropHighlighter.isValid()) { + TQRect rect=m_pList->mOldDropHighlighter; + m_pList->mOldDropHighlighter=TQRect(); + viewport()->tqrepaint(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(); + KIO::Job * job = 0L; + job = KIO::copy(urlList,tdir); + connect( job, TQT_SIGNAL( result( KIO::Job * ) ),TQT_SLOT( slotCopyFinished( KIO::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( KIO::Job *) + */ +void tdesvnfilelist::slotCopyFinished( KIO::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<KIO::CopyJob*>(job)->srcURLs(); + KURL turl = static_cast<KIO::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) { + KIO::Job*aJob = KIO::del(kioList); + connect(aJob,TQT_SIGNAL(result (KIO::Job *)),this,TQT_SLOT(slotDeleteFinished(KIO::Job*))); + dispDummy(); + } + if (m_deletePerfect && items.size()>0) { + m_SvnWrapper->makeDelete(items); + } + refreshCurrentTree(); + //m_pList->startScan(); +} + +/*! + \fn tdesvnfilelist::slotDeleteFinished(KIO::Job*) + */ +void tdesvnfilelist::slotDeleteFinished(KIO::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.tqminimumSizeHint()); + 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 tqlayout 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()->singletqStatus(item->fullName(),false,m_pList->m_remoteRevision)); + } catch (const svn::ClientException&e) { + item->setStat(new svn::tqStatus()); + 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()->tqrepaint(); + } +} + +/*! + \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( tqitemRect( 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(KGlobalSettings::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()->tqrepaint(); + } + 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").tqarg(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::tqStatus stat(fi->fileName(), &wc_stat); + + svn::StatusPtr stat(new svn::tqStatus(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::tqStatus> d; + while (_s) { + //_s->makePixmap(); + + if (!no_update) { + if (m_SvnWrapper->getUpdated(_s->stat()->path(),d) && d) { + _s->updatetqStatus(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->tqprocessEvents(20); + t.restart(); + } + ((FileListViewItem*)item)->setOpenNoBlock(true); + } + ++it; + } + } + setFocus(); + setUpdatesEnabled(true); + viewport()->tqrepaint(); + tqrepaint(); + 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->refreshtqStatus(); + 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" |