/*************************************************************************** * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class KdesvnFileListPrivate{ public: KdesvnFileListPrivate(); virtual ~KdesvnFileListPrivate() { if (m_DirWatch) { m_DirWatch->stopScan(); delete m_DirWatch; } delete m_fileTip; kdDebug()<<"Destructor KdesvnFileListPrivate done"< 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(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 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"<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" <getaddedItems(what,neweritems); dlist+=neweritems; bool ownupdates = true; //kdDebug() << "makeStatus on " << what << " created: " << dlist.count() << "items" <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"<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"<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( 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(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(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(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(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(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 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(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: "<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(_parent->firstChild()); } else { item = static_cast(firstChild()); } if (!item) return false; kapp->processEvents(); FileListViewItemList currentSync; currentSync.setAutoDelete(false); while (item) { currentSync.append(item); item = static_cast(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 "<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(qlvit.current()) ); ++qlvit; } kdDebug() << "Selected items " << m_SelectedItems->count() << endl; #endif } if (_parent) { item = static_cast(_parent->firstChild()); } else { item = static_cast(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(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(_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(target); if (!popup) { kdDebug()<<"Error getting popupMenu"<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"<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(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 metaData; TQDropEvent::Action action = event->action(); if (!event || m_pList->intern_dropRunning||!KURLDrag::decode( event, urlList, metaData)||urlList.count()<1) { return; } kdDebug()<<"slotDropped"<(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)<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(job)->srcURLs(); KURL turl = static_cast(job)->destURL(); TQString base = turl.path(1); KURL::List::iterator iter; TQValueList 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*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 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.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*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*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(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*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(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(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(item->firstChild()); while(item) { reinitItems(item); item = static_cast(item->nextSibling()); } } } /*! \fn tdesvnfilelist::slotInfo() */ void tdesvnfilelist::slotInfo() { TQPtrList 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 "<startDirTimer(); } void tdesvnfilelist::updateParents(FileListViewItem*item) { if (!item || !item->parent()) return; FileListViewItem*it = static_cast(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: "<m_remoteRevision); pm =m_SvnWrapper->propList(k->fullName(),rev,cache_Only); emit sigProplist(pm,isWorkingCopy(),k->fullName()); } void tdesvnfilelist::_dirwatchTimeout() { kdDebug()<<"dirtimer"<::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(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(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: "<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::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(firstChild()); } else { _s = static_cast(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(_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(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(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()->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(firstChild()); } else { _s = static_cast(startAt->firstChild()); } if (!_s) { return; } svn::SharedPointer 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(_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&dellist,const TQString&path) { m_SvnWrapper->changeProperties(pm,dellist,path); FileListViewItem* which = singleSelected(); kdDebug()<<(which?which->fullName():"nix") << " -> " << path<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"