2012-10-02 09:12:39 +02:00
/****************************************************************************
2008-12-02 12:01:29 +01:00
* *
2014-01-07 13:27:11 +01:00
* * Copyright ( C ) 2014 Digia Plc and / or its subsidiary ( - ies ) .
2012-10-02 09:12:39 +02:00
* * Contact : http : //www.qt-project.org/legal
2008-12-02 12:01:29 +01:00
* *
2012-10-02 09:12:39 +02:00
* * This file is part of Qt Creator .
2008-12-02 12:01:29 +01:00
* *
2012-10-02 09:12:39 +02:00
* * Commercial License Usage
* * Licensees holding valid commercial Qt licenses may use this file in
* * accordance with the commercial license agreement provided with the
* * Software or , alternatively , in accordance with the terms contained in
* * a written agreement between you and Digia . For licensing terms and
* * conditions see http : //qt.digia.com/licensing. For further information
* * use the contact form at http : //qt.digia.com/contact-us.
2008-12-02 14:17:16 +01:00
* *
2009-02-25 09:15:00 +01:00
* * GNU Lesser General Public License Usage
2012-10-02 09:12:39 +02:00
* * Alternatively , this file may be used under the terms of the GNU Lesser
* * General Public License version 2.1 as published by the Free Software
* * Foundation and appearing in the file LICENSE . LGPL included in the
* * packaging of this file . Please review the following information to
* * ensure the GNU Lesser General Public License version 2.1 requirements
* * will be met : http : //www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
* *
* * In addition , as a special exception , Digia gives you certain additional
* * rights . These rights are described in the Digia Qt LGPL Exception
2010-12-17 16:01:08 +01:00
* * version 1.1 , included in the file LGPL_EXCEPTION . txt in this package .
* *
2012-10-02 09:12:39 +02:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-12-02 16:19:05 +01:00
2008-12-02 12:01:29 +01:00
# include "perforceplugin.h"
2008-12-09 15:25:01 +01:00
2008-12-02 12:01:29 +01:00
# include "changenumberdialog.h"
2008-12-09 15:25:01 +01:00
# include "pendingchangesdialog.h"
2008-12-02 12:01:29 +01:00
# include "perforceconstants.h"
# include "perforceeditor.h"
2008-12-09 15:25:01 +01:00
# include "perforcesubmiteditor.h"
# include "perforceversioncontrol.h"
2009-12-11 16:43:39 +01:00
# include "perforcechecker.h"
2008-12-09 15:25:01 +01:00
# include "settingspage.h"
2008-12-02 12:01:29 +01:00
2009-01-13 13:39:31 +01:00
# include <coreplugin/actionmanager/actionmanager.h>
2010-03-18 10:59:06 +01:00
# include <coreplugin/actionmanager/actioncontainer.h>
# include <coreplugin/actionmanager/command.h>
2011-09-05 16:10:37 +02:00
# include <coreplugin/id.h>
2008-12-02 12:01:29 +01:00
# include <coreplugin/coreconstants.h>
2008-12-09 15:25:01 +01:00
# include <coreplugin/editormanager/editormanager.h>
2012-02-14 16:43:51 +01:00
# include <coreplugin/documentmanager.h>
2008-12-09 15:25:01 +01:00
# include <coreplugin/icore.h>
2008-12-02 12:01:29 +01:00
# include <coreplugin/messagemanager.h>
2008-12-09 15:25:01 +01:00
# include <coreplugin/mimedatabase.h>
2014-01-13 16:17:34 +01:00
# include <coreplugin/locator/commandlocator.h>
2008-12-09 15:25:01 +01:00
# include <utils/qtcassert.h>
2008-12-02 12:01:29 +01:00
# include <utils/synchronousprocess.h>
2009-05-15 15:41:00 +02:00
# include <utils/parameteraction.h>
2011-03-30 15:15:15 +02:00
# include <utils/fileutils.h>
2008-12-02 12:01:29 +01:00
# include <vcsbase/basevcseditorfactory.h>
# include <vcsbase/basevcssubmiteditorfactory.h>
# include <vcsbase/vcsbaseeditor.h>
2014-08-26 00:02:47 +02:00
# include <vcsbase/vcsoutputwindow.h>
2011-03-31 10:57:33 +02:00
# include <vcsbase/vcsbaseeditorparameterwidget.h>
2008-12-02 12:01:29 +01:00
2014-07-28 17:47:15 +02:00
# include <QAction>
2012-02-15 10:42:41 +01:00
# include <QDebug>
# include <QDir>
# include <QFileDialog>
2014-07-28 17:47:15 +02:00
# include <QFileInfo>
2012-02-15 10:42:41 +01:00
# include <QMainWindow>
# include <QMenu>
# include <QMessageBox>
2014-07-28 17:47:15 +02:00
# include <QSettings>
# include <QTextCodec>
# include <QtPlugin>
using namespace Core ;
using namespace Utils ;
using namespace VcsBase ;
2008-12-02 12:01:29 +01:00
2014-07-28 17:47:15 +02:00
namespace Perforce {
namespace Internal {
const char SUBMIT_CURRENT [ ] = " Perforce.SubmitCurrentLog " ;
const char DIFF_SELECTED [ ] = " Perforce.DiffSelectedFilesInLog " ;
const char SUBMIT_MIMETYPE [ ] = " text/vnd.qtcreator.p4.submit " ;
const char PERFORCE_SUBMIT_EDITOR_ID [ ] = " Perforce.SubmitEditor " ;
const char PERFORCE_SUBMIT_EDITOR_DISPLAY_NAME [ ] = QT_TRANSLATE_NOOP ( " VCS " , " Perforce.SubmitEditor " ) ;
const char PERFORCESUBMITEDITOR_CONTEXT [ ] = " Perforce Submit Editor " ;
const char PERFORCE_LOG_EDITOR_ID [ ] = " Perforce.LogEditor " ;
const char PERFORCE_LOG_EDITOR_DISPLAY_NAME [ ] = QT_TRANSLATE_NOOP ( " VCS " , " Perforce Log Editor " ) ;
const char PERFORCE_LOG_EDITOR_CONTEXT [ ] = " Perforce Log Editor " ;
const char PERFORCE_DIFF_EDITOR_ID [ ] = " Perforce.DiffEditor " ;
const char PERFORCE_DIFF_EDITOR_DISPLAY_NAME [ ] = QT_TRANSLATE_NOOP ( " VCS " , " Perforce Diff Editor " ) ;
const char PERFORCE_DIFF_EDITOR_CONTEXT [ ] = " Perforce Diff Editor " ;
const char PERFORCE_ANNOTATION_EDITOR_ID [ ] = " Perforce.AnnotationEditor " ;
const char PERFORCE_ANNOTATION_EDITOR_DISPLAY_NAME [ ] = QT_TRANSLATE_NOOP ( " VCS " , " Perforce Annotation Editor " ) ;
const char PERFORCE_ANNOTATION_EDITOR_CONTEXT [ ] = " Perforce Annotation Editor " ;
const VcsBaseEditorParameters editorParameters [ ] = {
2008-12-02 12:01:29 +01:00
{
2013-05-22 21:03:37 +03:00
VcsBase : : LogOutput ,
2014-07-28 17:47:15 +02:00
PERFORCE_LOG_EDITOR_ID ,
PERFORCE_LOG_EDITOR_DISPLAY_NAME ,
PERFORCE_LOG_EDITOR_CONTEXT ,
2013-05-21 23:37:47 +03:00
" text/vnd.qtcreator.p4.log " } ,
2012-01-07 12:31:48 +01:00
{ VcsBase : : AnnotateOutput ,
2014-07-28 17:47:15 +02:00
PERFORCE_ANNOTATION_EDITOR_ID ,
PERFORCE_ANNOTATION_EDITOR_DISPLAY_NAME ,
PERFORCE_ANNOTATION_EDITOR_CONTEXT ,
2013-05-21 23:37:47 +03:00
" text/vnd.qtcreator.p4.annotation " } ,
2012-01-07 12:31:48 +01:00
{ VcsBase : : DiffOutput ,
2014-07-28 17:47:15 +02:00
PERFORCE_DIFF_EDITOR_ID ,
PERFORCE_DIFF_EDITOR_DISPLAY_NAME ,
PERFORCE_DIFF_EDITOR_CONTEXT ,
2013-05-21 20:54:26 +03:00
" text/x-patch " }
2008-12-02 12:01:29 +01:00
} ;
// Utility to find a parameter set by type
2014-07-28 17:47:15 +02:00
static inline const VcsBaseEditorParameters * findType ( int ie )
2008-12-02 12:01:29 +01:00
{
2014-07-28 17:47:15 +02:00
const EditorContentType et = static_cast < EditorContentType > ( ie ) ;
return VcsBaseEditorWidget : : findType ( editorParameters , sizeof ( editorParameters ) / sizeof ( editorParameters [ 0 ] ) , et ) ;
2008-12-02 12:01:29 +01:00
}
static inline QString debugCodec ( const QTextCodec * c )
{
2012-09-21 13:54:38 +02:00
return c ? QString : : fromLatin1 ( c - > name ( ) ) : QString : : fromLatin1 ( " Null codec " ) ;
2008-12-02 12:01:29 +01:00
}
2009-12-11 16:43:39 +01:00
// Ensure adding "..." to relative paths which is p4's convention
// for the current directory
2013-08-06 15:14:54 +03:00
static inline QString perforceRelativeFileArguments ( const QString & args )
2009-12-11 16:43:39 +01:00
{
if ( args . isEmpty ( ) )
2013-08-06 15:14:54 +03:00
return QLatin1String ( " ... " ) ;
return args + QLatin1String ( " /... " ) ;
2009-12-11 16:43:39 +01:00
}
2014-07-28 17:47:15 +02:00
static inline QStringList perforceRelativeProjectDirectory ( const VcsBasePluginState & s )
2009-12-11 16:43:39 +01:00
{
2013-08-06 15:14:54 +03:00
return QStringList ( perforceRelativeFileArguments ( s . relativeCurrentProject ( ) ) ) ;
2009-12-11 16:43:39 +01:00
}
// Clean user setting off diff-binary for 'p4 resolve' and 'p4 diff'.
static inline QProcessEnvironment overrideDiffEnvironmentVariable ( )
{
QProcessEnvironment rc = QProcessEnvironment : : systemEnvironment ( ) ;
rc . remove ( QLatin1String ( " P4DIFF " ) ) ;
return rc ;
2009-03-10 11:02:12 +01:00
}
2014-07-28 17:47:15 +02:00
const char CMD_ID_PERFORCE_MENU [ ] = " Perforce.Menu " ;
const char CMD_ID_EDIT [ ] = " Perforce.Edit " ;
const char CMD_ID_ADD [ ] = " Perforce.Add " ;
const char CMD_ID_DELETE_FILE [ ] = " Perforce.Delete " ;
const char CMD_ID_OPENED [ ] = " Perforce.Opened " ;
const char CMD_ID_PROJECTLOG [ ] = " Perforce.ProjectLog " ;
const char CMD_ID_REPOSITORYLOG [ ] = " Perforce.RepositoryLog " ;
const char CMD_ID_REVERT [ ] = " Perforce.Revert " ;
const char CMD_ID_DIFF_CURRENT [ ] = " Perforce.DiffCurrent " ;
const char CMD_ID_DIFF_PROJECT [ ] = " Perforce.DiffProject " ;
const char CMD_ID_UPDATE_PROJECT [ ] = " Perforce.UpdateProject " ;
const char CMD_ID_REVERT_PROJECT [ ] = " Perforce.RevertProject " ;
const char CMD_ID_REVERT_UNCHANGED_PROJECT [ ] = " Perforce.RevertUnchangedProject " ;
const char CMD_ID_DIFF_ALL [ ] = " Perforce.DiffAll " ;
const char CMD_ID_SUBMIT [ ] = " Perforce.Submit " ;
const char CMD_ID_PENDING_CHANGES [ ] = " Perforce.PendingChanges " ;
const char CMD_ID_DESCRIBE [ ] = " Perforce.Describe " ;
const char CMD_ID_ANNOTATE_CURRENT [ ] = " Perforce.AnnotateCurrent " ;
const char CMD_ID_ANNOTATE [ ] = " Perforce.Annotate " ;
const char CMD_ID_FILELOG_CURRENT [ ] = " Perforce.FilelogCurrent " ;
const char CMD_ID_FILELOG [ ] = " Perforce.Filelog " ;
const char CMD_ID_UPDATEALL [ ] = " Perforce.UpdateAll " ;
2008-12-02 12:01:29 +01:00
////
// PerforcePlugin
////
2009-12-11 16:43:39 +01:00
PerforceResponse : : PerforceResponse ( ) :
error ( true ) ,
exitCode ( - 1 )
{
}
2013-08-02 12:54:36 +02:00
PerforcePlugin * PerforcePlugin : : m_instance = NULL ;
2008-12-02 12:01:29 +01:00
PerforcePlugin : : PerforcePlugin ( ) :
2010-02-12 16:03:08 +01:00
m_commandLocator ( 0 ) ,
2008-12-02 12:01:29 +01:00
m_editAction ( 0 ) ,
m_addAction ( 0 ) ,
m_deleteAction ( 0 ) ,
m_openedAction ( 0 ) ,
2009-12-11 16:43:39 +01:00
m_revertFileAction ( 0 ) ,
m_diffFileAction ( 0 ) ,
2008-12-02 12:01:29 +01:00
m_diffProjectAction ( 0 ) ,
2009-07-13 14:48:44 +02:00
m_updateProjectAction ( 0 ) ,
2009-12-11 16:43:39 +01:00
m_revertProjectAction ( 0 ) ,
m_revertUnchangedAction ( 0 ) ,
2008-12-02 12:01:29 +01:00
m_diffAllAction ( 0 ) ,
2009-12-11 16:43:39 +01:00
m_submitProjectAction ( 0 ) ,
2008-12-02 12:01:29 +01:00
m_pendingAction ( 0 ) ,
m_describeAction ( 0 ) ,
m_annotateCurrentAction ( 0 ) ,
m_annotateAction ( 0 ) ,
m_filelogCurrentAction ( 0 ) ,
m_filelogAction ( 0 ) ,
2010-01-07 11:33:30 +01:00
m_logProjectAction ( 0 ) ,
m_logRepositoryAction ( 0 ) ,
2009-03-20 10:16:18 +01:00
m_submitCurrentLogAction ( 0 ) ,
2009-07-13 14:48:44 +02:00
m_updateAllAction ( 0 ) ,
2009-03-20 10:16:18 +01:00
m_submitActionTriggered ( false ) ,
m_diffSelectedFiles ( 0 ) ,
m_undoAction ( 0 ) ,
2009-12-08 14:26:41 +01:00
m_redoAction ( 0 )
2008-12-02 12:01:29 +01:00
{
}
2014-07-28 17:47:15 +02:00
static const VcsBaseSubmitEditorParameters submitParameters = {
SUBMIT_MIMETYPE ,
PERFORCE_SUBMIT_EDITOR_ID ,
PERFORCE_SUBMIT_EDITOR_DISPLAY_NAME ,
PERFORCESUBMITEDITOR_CONTEXT ,
VcsBaseSubmitEditorParameters : : DiffFiles
2008-12-02 12:01:29 +01:00
} ;
2010-06-25 12:56:16 +02:00
bool PerforcePlugin : : initialize ( const QStringList & /* arguments */ , QString * errorMessage )
2008-12-02 12:01:29 +01:00
{
2014-07-28 17:47:15 +02:00
typedef VcsSubmitEditorFactory < PerforceSubmitEditor > PerforceSubmitEditorFactory ;
2008-12-02 12:01:29 +01:00
2011-06-04 21:07:34 +02:00
initializeVcs ( new PerforceVersionControl ( this ) ) ;
2009-12-08 14:26:41 +01:00
2014-07-28 17:47:15 +02:00
if ( ! MimeDatabase : : addMimeTypes ( QLatin1String ( " :/trolltech.perforce/Perforce.mimetypes.xml " ) , errorMessage ) )
2008-12-02 12:01:29 +01:00
return false ;
2013-08-02 12:54:36 +02:00
m_instance = this ;
2008-12-02 12:01:29 +01:00
2014-07-28 17:47:15 +02:00
m_settings . fromSettings ( ICore : : settings ( ) ) ;
2008-12-02 12:01:29 +01:00
2009-08-10 15:46:45 +02:00
addAutoReleasedObject ( new SettingsPage ) ;
2008-12-02 12:01:29 +01:00
// Editor factories
2009-08-10 15:46:45 +02:00
addAutoReleasedObject ( new PerforceSubmitEditorFactory ( & submitParameters ) ) ;
2008-12-02 12:01:29 +01:00
static const char * describeSlot = SLOT ( describe ( QString , QString ) ) ;
2014-07-28 17:47:15 +02:00
const int editorCount = sizeof ( editorParameters ) / sizeof ( editorParameters [ 0 ] ) ;
2014-08-21 20:43:33 +02:00
const auto widgetCreator = [ ] ( ) { return new PerforceEditorWidget ; } ;
2009-08-10 15:46:45 +02:00
for ( int i = 0 ; i < editorCount ; i + + )
2014-08-21 01:24:38 +02:00
addAutoReleasedObject ( new VcsEditorFactory ( editorParameters + i , widgetCreator , this , describeSlot ) ) ;
2008-12-02 12:01:29 +01:00
2010-02-12 16:03:08 +01:00
const QString prefix = QLatin1String ( " p4 " ) ;
2014-07-28 17:47:15 +02:00
m_commandLocator = new CommandLocator ( " Perforce " , prefix , prefix ) ;
2010-02-12 16:03:08 +01:00
addAutoReleasedObject ( m_commandLocator ) ;
2014-07-28 17:47:15 +02:00
ActionContainer * mtools = ActionManager : : actionContainer ( Core : : Constants : : M_TOOLS ) ;
2008-12-02 12:01:29 +01:00
2014-07-28 17:47:15 +02:00
ActionContainer * mperforce = ActionManager : : createMenu ( CMD_ID_PERFORCE_MENU ) ;
2008-12-02 12:01:29 +01:00
mperforce - > menu ( ) - > setTitle ( tr ( " &Perforce " ) ) ;
mtools - > addMenu ( mperforce ) ;
2009-12-08 14:26:41 +01:00
m_menuAction = mperforce - > menu ( ) - > menuAction ( ) ;
2008-12-02 12:01:29 +01:00
2014-07-28 17:47:15 +02:00
Context globalcontext ( Core : : Constants : : C_GLOBAL ) ;
Context perforcesubmitcontext ( PERFORCESUBMITEDITOR_CONTEXT ) ;
2008-12-02 12:01:29 +01:00
2009-01-14 13:17:53 +01:00
Core : : Command * command ;
2010-01-11 17:17:16 +01:00
2014-07-28 17:47:15 +02:00
m_diffFileAction = new ParameterAction ( tr ( " Diff Current File " ) , tr ( " Diff \" %1 \" " ) , ParameterAction : : EnabledWithParameter , this ) ;
command = ActionManager : : registerAction ( m_diffFileAction , CMD_ID_DIFF_CURRENT , globalcontext ) ;
2010-01-11 17:17:16 +01:00
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2012-01-06 17:13:18 +01:00
command - > setDescription ( tr ( " Diff Current File " ) ) ;
2010-01-11 17:17:16 +01:00
connect ( m_diffFileAction , SIGNAL ( triggered ( ) ) , this , SLOT ( diffCurrentFile ( ) ) ) ;
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2010-01-11 17:17:16 +01:00
2014-07-28 17:47:15 +02:00
m_annotateCurrentAction = new ParameterAction ( tr ( " Annotate Current File " ) , tr ( " Annotate \" %1 \" " ) , ParameterAction : : EnabledWithParameter , this ) ;
command = ActionManager : : registerAction ( m_annotateCurrentAction , CMD_ID_ANNOTATE_CURRENT , globalcontext ) ;
2010-01-11 17:17:16 +01:00
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2012-01-06 17:13:18 +01:00
command - > setDescription ( tr ( " Annotate Current File " ) ) ;
2010-01-11 17:17:16 +01:00
connect ( m_annotateCurrentAction , SIGNAL ( triggered ( ) ) , this , SLOT ( annotateCurrentFile ( ) ) ) ;
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2010-01-11 17:17:16 +01:00
2014-07-28 17:47:15 +02:00
m_filelogCurrentAction = new ParameterAction ( tr ( " Filelog Current File " ) , tr ( " Filelog \" %1 \" " ) , ParameterAction : : EnabledWithParameter , this ) ;
command = ActionManager : : registerAction ( m_filelogCurrentAction , CMD_ID_FILELOG_CURRENT , globalcontext ) ;
2010-01-11 17:17:16 +01:00
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2014-07-28 17:47:15 +02:00
command - > setDefaultKeySequence ( QKeySequence ( UseMacShortcuts ? tr ( " Meta+P,Meta+F " ) : tr ( " Alt+P,Alt+F " ) ) ) ;
2012-01-06 17:13:18 +01:00
command - > setDescription ( tr ( " Filelog Current File " ) ) ;
2010-01-11 17:17:16 +01:00
connect ( m_filelogCurrentAction , SIGNAL ( triggered ( ) ) , this , SLOT ( filelogCurrentFile ( ) ) ) ;
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2010-01-11 17:17:16 +01:00
2012-06-05 14:22:20 +02:00
mperforce - > addSeparator ( globalcontext ) ;
2008-12-02 12:01:29 +01:00
2014-07-28 17:47:15 +02:00
m_editAction = new ParameterAction ( tr ( " Edit " ) , tr ( " Edit \" %1 \" " ) , ParameterAction : : EnabledWithParameter , this ) ;
command = ActionManager : : registerAction ( m_editAction , CMD_ID_EDIT , globalcontext ) ;
2009-01-14 13:17:53 +01:00
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2014-07-28 17:47:15 +02:00
command - > setDefaultKeySequence ( QKeySequence ( UseMacShortcuts ? tr ( " Meta+P,Meta+E " ) : tr ( " Alt+P,Alt+E " ) ) ) ;
2012-01-06 17:13:18 +01:00
command - > setDescription ( tr ( " Edit File " ) ) ;
2008-12-02 12:01:29 +01:00
connect ( m_editAction , SIGNAL ( triggered ( ) ) , this , SLOT ( openCurrentFile ( ) ) ) ;
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2008-12-02 12:01:29 +01:00
2014-07-28 17:47:15 +02:00
m_addAction = new ParameterAction ( tr ( " Add " ) , tr ( " Add \" %1 \" " ) , ParameterAction : : EnabledWithParameter , this ) ;
command = ActionManager : : registerAction ( m_addAction , CMD_ID_ADD , globalcontext ) ;
2009-01-14 13:17:53 +01:00
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2014-07-28 17:47:15 +02:00
command - > setDefaultKeySequence ( QKeySequence ( UseMacShortcuts ? tr ( " Meta+P,Meta+A " ) : tr ( " Alt+P,Alt+A " ) ) ) ;
2012-01-06 17:13:18 +01:00
command - > setDescription ( tr ( " Add File " ) ) ;
2008-12-02 12:01:29 +01:00
connect ( m_addAction , SIGNAL ( triggered ( ) ) , this , SLOT ( addCurrentFile ( ) ) ) ;
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2008-12-02 12:01:29 +01:00
2014-07-28 17:47:15 +02:00
m_deleteAction = new ParameterAction ( tr ( " Delete... " ) , tr ( " Delete \" %1 \" ... " ) , ParameterAction : : EnabledWithParameter , this ) ;
command = ActionManager : : registerAction ( m_deleteAction , CMD_ID_DELETE_FILE , globalcontext ) ;
2009-01-14 13:17:53 +01:00
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2012-01-06 17:13:18 +01:00
command - > setDescription ( tr ( " Delete File " ) ) ;
2010-01-11 15:22:17 +01:00
connect ( m_deleteAction , SIGNAL ( triggered ( ) ) , this , SLOT ( promptToDeleteCurrentFile ( ) ) ) ;
2008-12-02 12:01:29 +01:00
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2008-12-02 12:01:29 +01:00
2014-07-28 17:47:15 +02:00
m_revertFileAction = new ParameterAction ( tr ( " Revert " ) , tr ( " Revert \" %1 \" " ) , ParameterAction : : EnabledWithParameter , this ) ;
command = ActionManager : : registerAction ( m_revertFileAction , CMD_ID_REVERT , globalcontext ) ;
2009-01-14 13:17:53 +01:00
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2014-07-28 17:47:15 +02:00
command - > setDefaultKeySequence ( QKeySequence ( UseMacShortcuts ? tr ( " Meta+P,Meta+R " ) : tr ( " Alt+P,Alt+R " ) ) ) ;
2012-01-06 17:13:18 +01:00
command - > setDescription ( tr ( " Revert File " ) ) ;
2009-12-11 16:43:39 +01:00
connect ( m_revertFileAction , SIGNAL ( triggered ( ) ) , this , SLOT ( revertCurrentFile ( ) ) ) ;
2008-12-02 12:01:29 +01:00
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2008-12-02 12:01:29 +01:00
2012-06-05 14:22:20 +02:00
mperforce - > addSeparator ( globalcontext ) ;
2008-12-02 12:01:29 +01:00
2009-07-13 14:48:44 +02:00
const QString diffProjectDefaultText = tr ( " Diff Current Project/Session " ) ;
2014-07-28 17:47:15 +02:00
m_diffProjectAction = new ParameterAction ( diffProjectDefaultText , tr ( " Diff Project \" %1 \" " ) , ParameterAction : : AlwaysEnabled , this ) ;
command = ActionManager : : registerAction ( m_diffProjectAction , CMD_ID_DIFF_PROJECT , globalcontext ) ;
2009-01-14 13:17:53 +01:00
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2014-07-28 17:47:15 +02:00
command - > setDefaultKeySequence ( QKeySequence ( UseMacShortcuts ? tr ( " Meta+P,Meta+D " ) : tr ( " Alt+P,Alt+D " ) ) ) ;
2012-01-06 17:13:18 +01:00
command - > setDescription ( diffProjectDefaultText ) ;
2008-12-02 12:01:29 +01:00
connect ( m_diffProjectAction , SIGNAL ( triggered ( ) ) , this , SLOT ( diffCurrentProject ( ) ) ) ;
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2008-12-02 12:01:29 +01:00
2014-07-28 17:47:15 +02:00
m_logProjectAction = new ParameterAction ( tr ( " Log Project " ) , tr ( " Log Project \" %1 \" " ) , ParameterAction : : EnabledWithParameter , this ) ;
command = ActionManager : : registerAction ( m_logProjectAction , CMD_ID_PROJECTLOG , globalcontext ) ;
2010-01-07 11:33:30 +01:00
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
connect ( m_logProjectAction , SIGNAL ( triggered ( ) ) , this , SLOT ( logProject ( ) ) ) ;
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2010-01-07 11:33:30 +01:00
2014-07-28 17:47:15 +02:00
m_submitProjectAction = new ParameterAction ( tr ( " Submit Project " ) , tr ( " Submit Project \" %1 \" " ) , ParameterAction : : EnabledWithParameter , this ) ;
command = ActionManager : : registerAction ( m_submitProjectAction , CMD_ID_SUBMIT , globalcontext ) ;
2009-12-11 16:43:39 +01:00
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2014-07-28 17:47:15 +02:00
command - > setDefaultKeySequence ( QKeySequence ( UseMacShortcuts ? tr ( " Meta+P,Meta+S " ) : tr ( " Alt+P,Alt+S " ) ) ) ;
2009-12-11 16:43:39 +01:00
connect ( m_submitProjectAction , SIGNAL ( triggered ( ) ) , this , SLOT ( startSubmitProject ( ) ) ) ;
2008-12-02 12:01:29 +01:00
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2008-12-02 12:01:29 +01:00
2009-12-11 16:43:39 +01:00
const QString updateProjectDefaultText = tr ( " Update Current Project " ) ;
2014-07-28 17:47:15 +02:00
m_updateProjectAction = new ParameterAction ( updateProjectDefaultText , tr ( " Update Project \" %1 \" " ) , ParameterAction : : AlwaysEnabled , this ) ;
command = ActionManager : : registerAction ( m_updateProjectAction , CMD_ID_UPDATE_PROJECT , globalcontext ) ;
2012-01-06 17:13:18 +01:00
command - > setDescription ( updateProjectDefaultText ) ;
2009-07-13 14:48:44 +02:00
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
connect ( m_updateProjectAction , SIGNAL ( triggered ( ) ) , this , SLOT ( updateCurrentProject ( ) ) ) ;
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2009-07-13 14:48:44 +02:00
2014-07-28 17:47:15 +02:00
m_revertUnchangedAction = new ParameterAction ( tr ( " Revert Unchanged " ) , tr ( " Revert Unchanged Files of Project \" %1 \" " ) , ParameterAction : : EnabledWithParameter , this ) ;
command = ActionManager : : registerAction ( m_revertUnchangedAction , CMD_ID_REVERT_UNCHANGED_PROJECT , globalcontext ) ;
2010-01-11 17:17:16 +01:00
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
connect ( m_revertUnchangedAction , SIGNAL ( triggered ( ) ) , this , SLOT ( revertUnchangedCurrentProject ( ) ) ) ;
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2010-01-11 17:17:16 +01:00
2014-07-28 17:47:15 +02:00
m_revertProjectAction = new ParameterAction ( tr ( " Revert Project " ) , tr ( " Revert Project \" %1 \" " ) , ParameterAction : : EnabledWithParameter , this ) ;
command = ActionManager : : registerAction ( m_revertProjectAction , CMD_ID_REVERT_PROJECT , globalcontext ) ;
2009-12-11 16:43:39 +01:00
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
connect ( m_revertProjectAction , SIGNAL ( triggered ( ) ) , this , SLOT ( revertCurrentProject ( ) ) ) ;
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2009-12-11 16:43:39 +01:00
2012-06-05 14:22:20 +02:00
mperforce - > addSeparator ( globalcontext ) ;
2010-01-11 17:17:16 +01:00
m_diffAllAction = new QAction ( tr ( " Diff Opened Files " ) , this ) ;
2014-07-28 17:47:15 +02:00
command = ActionManager : : registerAction ( m_diffAllAction , CMD_ID_DIFF_ALL , globalcontext ) ;
2010-01-11 17:17:16 +01:00
connect ( m_diffAllAction , SIGNAL ( triggered ( ) ) , this , SLOT ( diffAllOpened ( ) ) ) ;
2009-12-11 16:43:39 +01:00
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2009-12-11 16:43:39 +01:00
2010-01-11 17:17:16 +01:00
m_openedAction = new QAction ( tr ( " Opened " ) , this ) ;
2014-07-28 17:47:15 +02:00
command = ActionManager : : registerAction ( m_openedAction , CMD_ID_OPENED , globalcontext ) ;
command - > setDefaultKeySequence ( QKeySequence ( UseMacShortcuts ? tr ( " Meta+P,Meta+O " ) : tr ( " Alt+P,Alt+O " ) ) ) ;
2010-01-11 17:17:16 +01:00
connect ( m_openedAction , SIGNAL ( triggered ( ) ) , this , SLOT ( printOpenedFileList ( ) ) ) ;
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2010-01-11 17:17:16 +01:00
m_logRepositoryAction = new QAction ( tr ( " Repository Log " ) , this ) ;
2014-07-28 17:47:15 +02:00
command = ActionManager : : registerAction ( m_logRepositoryAction , CMD_ID_REPOSITORYLOG , globalcontext ) ;
2010-01-11 17:17:16 +01:00
connect ( m_logRepositoryAction , SIGNAL ( triggered ( ) ) , this , SLOT ( logRepository ( ) ) ) ;
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2010-01-11 17:17:16 +01:00
m_pendingAction = new QAction ( tr ( " Pending Changes... " ) , this ) ;
2014-07-28 17:47:15 +02:00
command = ActionManager : : registerAction ( m_pendingAction , CMD_ID_PENDING_CHANGES , globalcontext ) ;
2010-01-11 17:17:16 +01:00
connect ( m_pendingAction , SIGNAL ( triggered ( ) ) , this , SLOT ( printPendingChanges ( ) ) ) ;
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2010-01-11 17:17:16 +01:00
m_updateAllAction = new QAction ( tr ( " Update All " ) , this ) ;
2014-07-28 17:47:15 +02:00
command = ActionManager : : registerAction ( m_updateAllAction , CMD_ID_UPDATEALL , globalcontext ) ;
2010-01-11 17:17:16 +01:00
connect ( m_updateAllAction , SIGNAL ( triggered ( ) ) , this , SLOT ( updateAll ( ) ) ) ;
2008-12-02 12:01:29 +01:00
mperforce - > addAction ( command ) ;
2010-02-12 16:03:08 +01:00
m_commandLocator - > appendCommand ( command ) ;
2008-12-02 12:01:29 +01:00
2012-06-05 14:22:20 +02:00
mperforce - > addSeparator ( globalcontext ) ;
2010-01-11 17:17:16 +01:00
2008-12-02 12:01:29 +01:00
m_describeAction = new QAction ( tr ( " Describe... " ) , this ) ;
2014-07-28 17:47:15 +02:00
command = ActionManager : : registerAction ( m_describeAction , CMD_ID_DESCRIBE , globalcontext ) ;
2008-12-02 12:01:29 +01:00
connect ( m_describeAction , SIGNAL ( triggered ( ) ) , this , SLOT ( describeChange ( ) ) ) ;
mperforce - > addAction ( command ) ;
m_annotateAction = new QAction ( tr ( " Annotate... " ) , this ) ;
2014-07-28 17:47:15 +02:00
command = ActionManager : : registerAction ( m_annotateAction , CMD_ID_ANNOTATE , globalcontext ) ;
2008-12-02 12:01:29 +01:00
connect ( m_annotateAction , SIGNAL ( triggered ( ) ) , this , SLOT ( annotate ( ) ) ) ;
mperforce - > addAction ( command ) ;
m_filelogAction = new QAction ( tr ( " Filelog... " ) , this ) ;
2014-07-28 17:47:15 +02:00
command = ActionManager : : registerAction ( m_filelogAction , CMD_ID_FILELOG , globalcontext ) ;
2008-12-02 12:01:29 +01:00
connect ( m_filelogAction , SIGNAL ( triggered ( ) ) , this , SLOT ( filelog ( ) ) ) ;
mperforce - > addAction ( command ) ;
2014-07-28 17:47:15 +02:00
m_submitCurrentLogAction = new QAction ( VcsBaseSubmitEditor : : submitIcon ( ) , tr ( " Submit " ) , this ) ;
command = ActionManager : : registerAction ( m_submitCurrentLogAction , SUBMIT_CURRENT , perforcesubmitcontext ) ;
2010-08-19 10:04:21 +02:00
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2008-12-02 12:01:29 +01:00
connect ( m_submitCurrentLogAction , SIGNAL ( triggered ( ) ) , this , SLOT ( submitCurrentLog ( ) ) ) ;
2014-07-28 17:47:15 +02:00
m_diffSelectedFiles = new QAction ( VcsBaseSubmitEditor : : diffIcon ( ) , tr ( " Diff &Selected Files " ) , this ) ;
command = ActionManager : : registerAction ( m_diffSelectedFiles , DIFF_SELECTED , perforcesubmitcontext ) ;
2008-12-02 12:01:29 +01:00
m_undoAction = new QAction ( tr ( " &Undo " ) , this ) ;
2014-07-28 17:47:15 +02:00
command = ActionManager : : registerAction ( m_undoAction , Core : : Constants : : UNDO , perforcesubmitcontext ) ;
2008-12-02 12:01:29 +01:00
m_redoAction = new QAction ( tr ( " &Redo " ) , this ) ;
2014-07-28 17:47:15 +02:00
command = ActionManager : : registerAction ( m_redoAction , Core : : Constants : : REDO , perforcesubmitcontext ) ;
2008-12-02 12:01:29 +01:00
return true ;
}
void PerforcePlugin : : extensionsInitialized ( )
{
2014-07-28 17:47:15 +02:00
VcsBasePlugin : : extensionsInitialized ( ) ;
2009-12-11 16:43:39 +01:00
getTopLevel ( ) ;
2008-12-02 12:01:29 +01:00
}
void PerforcePlugin : : openCurrentFile ( )
{
2014-07-28 17:47:15 +02:00
const VcsBasePluginState state = currentState ( ) ;
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( state . hasFile ( ) , return ) ;
2009-12-11 16:43:39 +01:00
vcsOpen ( state . currentFileTopLevel ( ) , state . relativeCurrentFile ( ) ) ;
2008-12-02 12:01:29 +01:00
}
void PerforcePlugin : : addCurrentFile ( )
{
2014-07-28 17:47:15 +02:00
const VcsBasePluginState state = currentState ( ) ;
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( state . hasFile ( ) , return ) ;
2009-12-11 16:43:39 +01:00
vcsAdd ( state . currentFileTopLevel ( ) , state . relativeCurrentFile ( ) ) ;
2008-12-02 12:01:29 +01:00
}
void PerforcePlugin : : revertCurrentFile ( )
{
2014-07-28 17:47:15 +02:00
const VcsBasePluginState state = currentState ( ) ;
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( state . hasFile ( ) , return ) ;
2009-12-11 16:43:39 +01:00
2014-07-28 17:47:15 +02:00
QTextCodec * codec = VcsBaseEditorWidget : : getCodec ( state . currentFile ( ) ) ;
2008-12-02 12:01:29 +01:00
QStringList args ;
2009-12-11 16:43:39 +01:00
args < < QLatin1String ( " diff " ) < < QLatin1String ( " -sa " ) < < state . relativeCurrentFile ( ) ;
PerforceResponse result = runP4Cmd ( state . currentFileTopLevel ( ) , args ,
RunFullySynchronous | CommandToWindow | StdErrToWindow | ErrorToWindow ,
QStringList ( ) , QByteArray ( ) , codec ) ;
2008-12-02 12:01:29 +01:00
if ( result . error )
return ;
2009-12-11 16:43:39 +01:00
// "foo.cpp - file(s) not opened on this client."
2011-08-02 09:40:04 +00:00
// also revert when the output is empty: The file is unchanged but open then.
if ( result . stdOut . contains ( QLatin1String ( " - " ) ) | | result . stdErr . contains ( QLatin1String ( " - " ) ) )
2009-12-11 16:43:39 +01:00
return ;
2008-12-02 12:01:29 +01:00
2011-08-02 09:40:04 +00:00
bool doNotRevert = false ;
if ( ! result . stdOut . isEmpty ( ) )
2014-07-28 17:47:15 +02:00
doNotRevert = ( QMessageBox : : warning ( ICore : : dialogParent ( ) , tr ( " p4 revert " ) ,
2011-08-02 09:40:04 +00:00
tr ( " The file has been changed. Do you want to revert it? " ) ,
QMessageBox : : Yes , QMessageBox : : No ) = = QMessageBox : : No ) ;
2009-12-11 16:43:39 +01:00
if ( doNotRevert )
return ;
2008-12-02 12:01:29 +01:00
2014-07-28 17:47:15 +02:00
FileChangeBlocker fcb ( state . currentFile ( ) ) ;
2009-12-11 16:43:39 +01:00
args . clear ( ) ;
args < < QLatin1String ( " revert " ) < < state . relativeCurrentFile ( ) ;
PerforceResponse result2 = runP4Cmd ( state . currentFileTopLevel ( ) , args ,
CommandToWindow | StdOutToWindow | StdErrToWindow | ErrorToWindow ) ;
2009-11-11 14:32:54 +01:00
if ( ! result2 . error )
2009-12-11 16:43:39 +01:00
perforceVersionControl ( ) - > emitFilesChanged ( QStringList ( state . currentFile ( ) ) ) ;
2008-12-02 12:01:29 +01:00
}
void PerforcePlugin : : diffCurrentFile ( )
{
2014-07-28 17:47:15 +02:00
const VcsBasePluginState state = currentState ( ) ;
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( state . hasFile ( ) , return ) ;
2009-12-11 16:43:39 +01:00
p4Diff ( state . currentFileTopLevel ( ) , QStringList ( state . relativeCurrentFile ( ) ) ) ;
2008-12-02 12:01:29 +01:00
}
void PerforcePlugin : : diffCurrentProject ( )
{
2014-07-28 17:47:15 +02:00
const VcsBasePluginState state = currentState ( ) ;
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( state . hasProject ( ) , return ) ;
2009-12-11 16:43:39 +01:00
p4Diff ( state . currentProjectTopLevel ( ) , perforceRelativeProjectDirectory ( state ) ) ;
2008-12-02 12:01:29 +01:00
}
void PerforcePlugin : : diffAllOpened ( )
{
2009-12-11 16:43:39 +01:00
p4Diff ( m_settings . topLevel ( ) , QStringList ( ) ) ;
2008-12-02 12:01:29 +01:00
}
2009-12-11 16:43:39 +01:00
void PerforcePlugin : : updateCurrentProject ( )
2009-07-13 14:48:44 +02:00
{
2014-07-28 17:47:15 +02:00
const VcsBasePluginState state = currentState ( ) ;
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( state . hasProject ( ) , return ) ;
2009-12-11 16:43:39 +01:00
updateCheckout ( state . currentProjectTopLevel ( ) , perforceRelativeProjectDirectory ( state ) ) ;
2009-07-13 14:48:44 +02:00
}
2009-12-11 16:43:39 +01:00
void PerforcePlugin : : updateAll ( )
{
updateCheckout ( m_settings . topLevel ( ) ) ;
}
void PerforcePlugin : : revertCurrentProject ( )
2009-07-13 14:48:44 +02:00
{
2014-07-28 17:47:15 +02:00
const VcsBasePluginState state = currentState ( ) ;
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( state . hasProject ( ) , return ) ;
2009-12-11 16:43:39 +01:00
const QString msg = tr ( " Do you want to revert all changes to the project \" %1 \" ? " ) . arg ( state . currentProjectName ( ) ) ;
2014-07-28 17:47:15 +02:00
if ( QMessageBox : : warning ( ICore : : dialogParent ( ) , tr ( " p4 revert " ) , msg , QMessageBox : : Yes , QMessageBox : : No ) = = QMessageBox : : No )
2009-07-13 14:48:44 +02:00
return ;
2009-12-11 16:43:39 +01:00
revertProject ( state . currentProjectTopLevel ( ) , perforceRelativeProjectDirectory ( state ) , false ) ;
2009-07-13 14:48:44 +02:00
}
2009-12-11 16:43:39 +01:00
void PerforcePlugin : : revertUnchangedCurrentProject ( )
2009-07-13 14:48:44 +02:00
{
2009-12-11 16:43:39 +01:00
// revert -a.
2014-07-28 17:47:15 +02:00
const VcsBasePluginState state = currentState ( ) ;
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( state . hasProject ( ) , return ) ;
2009-12-11 16:43:39 +01:00
revertProject ( state . currentProjectTopLevel ( ) , perforceRelativeProjectDirectory ( state ) , true ) ;
2009-07-13 14:48:44 +02:00
}
2009-12-11 16:43:39 +01:00
bool PerforcePlugin : : revertProject ( const QString & workingDir , const QStringList & pathArgs , bool unchangedOnly )
{
QStringList args ( QLatin1String ( " revert " ) ) ;
if ( unchangedOnly )
args . push_back ( QLatin1String ( " -a " ) ) ;
args . append ( pathArgs ) ;
const PerforceResponse resp = runP4Cmd ( workingDir , args ,
RunFullySynchronous | CommandToWindow | StdOutToWindow | StdErrToWindow | ErrorToWindow ) ;
return ! resp . error ;
}
void PerforcePlugin : : updateCheckout ( const QString & workingDir , const QStringList & dirs )
2009-07-13 14:48:44 +02:00
{
QStringList args ( QLatin1String ( " sync " ) ) ;
args . append ( dirs ) ;
2009-12-11 16:43:39 +01:00
const PerforceResponse resp = runP4Cmd ( workingDir , args ,
CommandToWindow | StdOutToWindow | StdErrToWindow | ErrorToWindow ) ;
if ( dirs . empty ( ) ) {
if ( ! workingDir . isEmpty ( ) )
perforceVersionControl ( ) - > emitRepositoryChanged ( workingDir ) ;
} else {
const QChar slash = QLatin1Char ( ' / ' ) ;
2012-11-28 20:44:03 +02:00
foreach ( const QString & dir , dirs )
2009-12-11 16:43:39 +01:00
perforceVersionControl ( ) - > emitRepositoryChanged ( workingDir + slash + dir ) ;
}
2009-07-13 14:48:44 +02:00
}
2008-12-02 12:01:29 +01:00
void PerforcePlugin : : printOpenedFileList ( )
{
2009-12-15 14:20:06 +01:00
const PerforceResponse perforceResponse
= runP4Cmd ( m_settings . topLevel ( ) , QStringList ( QLatin1String ( " opened " ) ) ,
CommandToWindow | StdErrToWindow | ErrorToWindow ) ;
if ( perforceResponse . error | | perforceResponse . stdOut . isEmpty ( ) )
return ;
// reformat "//depot/file.cpp#1 - description" into "file.cpp # - description"
// for context menu opening to work. This produces absolute paths, then.
QString errorMessage ;
QString mapped ;
const QChar delimiter = QLatin1Char ( ' # ' ) ;
foreach ( const QString & line , perforceResponse . stdOut . split ( QLatin1Char ( ' \n ' ) ) ) {
mapped . clear ( ) ;
const int delimiterPos = line . indexOf ( delimiter ) ;
if ( delimiterPos > 0 )
mapped = fileNameFromPerforceName ( line . left ( delimiterPos ) , true , & errorMessage ) ;
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
if ( mapped . isEmpty ( ) )
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : appendSilently ( line ) ;
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
else
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : appendSilently ( mapped + QLatin1Char ( ' ' ) + line . mid ( delimiterPos ) ) ;
2009-12-15 14:20:06 +01:00
}
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : instance ( ) - > popup ( IOutputPane : : ModeSwitch | IOutputPane : : WithFocus ) ;
2008-12-02 12:01:29 +01:00
}
2009-12-11 16:43:39 +01:00
void PerforcePlugin : : startSubmitProject ( )
2008-12-02 12:01:29 +01:00
{
2009-05-27 16:17:24 +02:00
2013-04-18 12:06:43 +02:00
if ( raiseSubmitEditor ( ) )
2008-12-02 12:01:29 +01:00
return ;
2009-09-22 12:23:44 +02:00
if ( isCommitEditorOpen ( ) ) {
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : appendWarning ( tr ( " Another submit is currently executed. " ) ) ;
2008-12-02 12:01:29 +01:00
return ;
}
2014-07-28 17:47:15 +02:00
const VcsBasePluginState state = currentState ( ) ;
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( state . hasProject ( ) , return ) ;
2009-12-11 16:43:39 +01:00
// Revert all unchanged files.
if ( ! revertProject ( state . currentProjectTopLevel ( ) , perforceRelativeProjectDirectory ( state ) , true ) )
return ;
// Start a change
QStringList args ;
2008-12-02 12:01:29 +01:00
2009-12-11 16:43:39 +01:00
args < < QLatin1String ( " change " ) < < QLatin1String ( " -o " ) ;
PerforceResponse result = runP4Cmd ( state . currentProjectTopLevel ( ) , args ,
RunFullySynchronous | CommandToWindow | StdErrToWindow | ErrorToWindow ) ;
2008-12-02 12:01:29 +01:00
if ( result . error ) {
2009-09-22 12:23:44 +02:00
cleanCommitMessageFile ( ) ;
2008-12-02 12:01:29 +01:00
return ;
}
2014-07-28 17:47:15 +02:00
TempFileSaver saver ;
2011-03-30 15:15:15 +02:00
saver . setAutoRemove ( false ) ;
2012-09-21 13:54:38 +02:00
saver . write ( result . stdOut . toLatin1 ( ) ) ;
2011-03-30 15:15:15 +02:00
if ( ! saver . finalize ( ) ) {
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : appendError ( saver . errorString ( ) ) ;
2011-03-30 15:15:15 +02:00
cleanCommitMessageFile ( ) ;
return ;
}
m_commitMessageFileName = saver . fileName ( ) ;
2008-12-02 12:01:29 +01:00
2009-12-11 16:43:39 +01:00
args . clear ( ) ;
args < < QLatin1String ( " fstat " ) ;
args . append ( perforceRelativeProjectDirectory ( state ) ) ;
PerforceResponse fstatResult = runP4Cmd ( state . currentProjectTopLevel ( ) , args ,
RunFullySynchronous | CommandToWindow | StdErrToWindow | ErrorToWindow ) ;
if ( fstatResult . error ) {
2009-09-22 12:23:44 +02:00
cleanCommitMessageFile ( ) ;
2008-12-02 12:01:29 +01:00
return ;
}
2009-12-11 16:43:39 +01:00
QStringList fstatLines = fstatResult . stdOut . split ( QLatin1Char ( ' \n ' ) ) ;
2008-12-02 12:01:29 +01:00
QStringList depotFileNames ;
2009-12-11 16:43:39 +01:00
foreach ( const QString & line , fstatLines ) {
2010-02-01 12:43:56 +01:00
if ( line . startsWith ( QLatin1String ( " ... depotFile " ) ) )
2008-12-02 12:01:29 +01:00
depotFileNames . append ( line . mid ( 14 ) ) ;
}
if ( depotFileNames . isEmpty ( ) ) {
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : appendWarning ( tr ( " Project has no files " ) ) ;
2009-09-22 12:23:44 +02:00
cleanCommitMessageFile ( ) ;
2008-12-02 12:01:29 +01:00
return ;
}
2009-09-22 12:23:44 +02:00
openPerforceSubmitEditor ( m_commitMessageFileName , depotFileNames ) ;
2008-12-02 12:01:29 +01:00
}
2014-07-28 17:47:15 +02:00
IEditor * PerforcePlugin : : openPerforceSubmitEditor ( const QString & fileName , const QStringList & depotFileNames )
2008-12-02 12:01:29 +01:00
{
2014-07-28 17:47:15 +02:00
IEditor * editor = EditorManager : : openEditor ( fileName , PERFORCE_SUBMIT_EDITOR_ID ) ;
2009-08-25 16:08:52 +02:00
PerforceSubmitEditor * submitEditor = static_cast < PerforceSubmitEditor * > ( editor ) ;
2013-04-18 12:06:43 +02:00
setSubmitEditor ( submitEditor ) ;
2008-12-02 12:01:29 +01:00
submitEditor - > restrictToProjectFiles ( depotFileNames ) ;
2009-01-13 14:06:42 +01:00
submitEditor - > registerActions ( m_undoAction , m_redoAction , m_submitCurrentLogAction , m_diffSelectedFiles ) ;
2009-12-11 16:43:39 +01:00
connect ( submitEditor , SIGNAL ( diffSelectedFiles ( QStringList ) ) , this , SLOT ( slotSubmitDiff ( QStringList ) ) ) ;
2009-12-14 10:56:50 +01:00
submitEditor - > setCheckScriptWorkingDirectory ( m_commitWorkingDirectory ) ;
2008-12-02 12:01:29 +01:00
return editor ;
}
void PerforcePlugin : : printPendingChanges ( )
{
qApp - > setOverrideCursor ( Qt : : WaitCursor ) ;
2014-07-28 17:47:15 +02:00
PendingChangesDialog dia ( pendingChangesData ( ) , ICore : : mainWindow ( ) ) ;
2008-12-02 12:01:29 +01:00
qApp - > restoreOverrideCursor ( ) ;
if ( dia . exec ( ) = = QDialog : : Accepted ) {
2008-12-04 16:24:15 +01:00
const int i = dia . changeNumber ( ) ;
QStringList args ( QLatin1String ( " submit " ) ) ;
args < < QLatin1String ( " -c " ) < < QString : : number ( i ) ;
2009-12-11 16:43:39 +01:00
runP4Cmd ( m_settings . topLevel ( ) , args ,
CommandToWindow | StdOutToWindow | StdErrToWindow | ErrorToWindow ) ;
2008-12-02 12:01:29 +01:00
}
}
void PerforcePlugin : : describeChange ( )
{
ChangeNumberDialog dia ;
if ( dia . exec ( ) = = QDialog : : Accepted & & dia . number ( ) > 0 )
describe ( QString ( ) , QString : : number ( dia . number ( ) ) ) ;
}
void PerforcePlugin : : annotateCurrentFile ( )
{
2014-07-28 17:47:15 +02:00
const VcsBasePluginState state = currentState ( ) ;
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( state . hasFile ( ) , return ) ;
2009-12-11 16:43:39 +01:00
annotate ( state . currentFileTopLevel ( ) , state . relativeCurrentFile ( ) ) ;
2008-12-02 12:01:29 +01:00
}
void PerforcePlugin : : annotate ( )
{
2014-07-28 17:47:15 +02:00
const QString file = QFileDialog : : getOpenFileName ( ICore : : dialogParent ( ) , tr ( " p4 annotate " ) ) ;
2009-12-11 16:43:39 +01:00
if ( ! file . isEmpty ( ) ) {
const QFileInfo fi ( file ) ;
annotate ( fi . absolutePath ( ) , fi . fileName ( ) ) ;
}
2008-12-02 12:01:29 +01:00
}
2013-10-06 20:47:29 +03:00
void PerforcePlugin : : vcsAnnotate ( const QString & workingDirectory , const QString & file ,
const QString & revision , int lineNumber )
2010-01-06 17:24:40 +01:00
{
2013-10-06 20:47:29 +03:00
annotate ( workingDirectory , file , revision , lineNumber ) ;
2010-01-06 17:24:40 +01:00
}
void PerforcePlugin : : annotate ( const QString & workingDir ,
const QString & fileName ,
const QString & changeList /* = QString() */ ,
int lineNumber /* = -1 */ )
2008-12-02 12:01:29 +01:00
{
2009-12-11 16:43:39 +01:00
const QStringList files = QStringList ( fileName ) ;
2014-07-28 17:47:15 +02:00
QTextCodec * codec = VcsBaseEditorWidget : : getCodec ( workingDir , files ) ;
const QString id = VcsBaseEditorWidget : : getTitleId ( workingDir , files , changeList ) ;
const QString source = VcsBaseEditorWidget : : getSource ( workingDir , files ) ;
2008-12-02 12:01:29 +01:00
QStringList args ;
2010-01-06 17:24:40 +01:00
args < < QLatin1String ( " annotate " ) < < QLatin1String ( " -cqi " ) ;
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
if ( changeList . isEmpty ( ) )
2010-01-06 17:24:40 +01:00
args < < fileName ;
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
else
2010-01-06 17:24:40 +01:00
args < < ( fileName + QLatin1Char ( ' @ ' ) + changeList ) ;
2009-12-11 16:43:39 +01:00
const PerforceResponse result = runP4Cmd ( workingDir , args ,
CommandToWindow | StdErrToWindow | ErrorToWindow ,
QStringList ( ) , QByteArray ( ) , codec ) ;
2008-12-02 12:01:29 +01:00
if ( ! result . error ) {
2010-01-06 17:24:40 +01:00
if ( lineNumber < 1 )
2014-07-28 17:47:15 +02:00
lineNumber = VcsBaseEditorWidget : : lineNumberOfCurrentEditor ( ) ;
IEditor * ed = showOutputInEditor ( tr ( " p4 annotate %1 " ) . arg ( id ) ,
result . stdOut , VcsBase : : AnnotateOutput ,
source , codec ) ;
VcsBaseEditorWidget : : gotoLineOfEditor ( ed , lineNumber ) ;
2008-12-02 12:01:29 +01:00
}
}
void PerforcePlugin : : filelogCurrentFile ( )
{
2014-07-28 17:47:15 +02:00
const VcsBasePluginState state = currentState ( ) ;
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( state . hasFile ( ) , return ) ;
2013-08-06 15:14:54 +03:00
filelog ( state . currentFileTopLevel ( ) , state . relativeCurrentFile ( ) , true ) ;
2008-12-02 12:01:29 +01:00
}
void PerforcePlugin : : filelog ( )
{
2014-07-28 17:47:15 +02:00
const QString file = QFileDialog : : getOpenFileName ( ICore : : dialogParent ( ) , tr ( " p4 filelog " ) ) ;
2009-12-11 16:43:39 +01:00
if ( ! file . isEmpty ( ) ) {
const QFileInfo fi ( file ) ;
2013-08-06 15:14:54 +03:00
filelog ( fi . absolutePath ( ) , fi . fileName ( ) ) ;
2009-12-11 16:43:39 +01:00
}
2008-12-02 12:01:29 +01:00
}
2010-01-07 11:33:30 +01:00
void PerforcePlugin : : logProject ( )
{
2014-07-28 17:47:15 +02:00
const VcsBasePluginState state = currentState ( ) ;
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( state . hasProject ( ) , return ) ;
2010-01-07 11:33:30 +01:00
filelog ( state . currentProjectTopLevel ( ) , perforceRelativeFileArguments ( state . relativeCurrentProject ( ) ) ) ;
}
void PerforcePlugin : : logRepository ( )
{
2014-07-28 17:47:15 +02:00
const VcsBasePluginState state = currentState ( ) ;
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( state . hasTopLevel ( ) , return ) ;
2013-08-06 15:14:54 +03:00
filelog ( state . topLevel ( ) , perforceRelativeFileArguments ( QString ( ) ) ) ;
2010-01-07 11:33:30 +01:00
}
2013-08-06 15:14:54 +03:00
void PerforcePlugin : : filelog ( const QString & workingDir , const QString & fileName ,
2010-01-07 11:33:30 +01:00
bool enableAnnotationContextMenu )
2008-12-02 12:01:29 +01:00
{
2014-07-28 17:47:15 +02:00
const QString id = VcsBaseEditorWidget : : getTitleId ( workingDir , QStringList ( fileName ) ) ;
QTextCodec * codec = VcsBaseEditorWidget : : getCodec ( workingDir , QStringList ( fileName ) ) ;
2008-12-02 12:01:29 +01:00
QStringList args ;
2009-12-11 16:43:39 +01:00
args < < QLatin1String ( " filelog " ) < < QLatin1String ( " -li " ) ;
2010-01-07 11:33:30 +01:00
if ( m_settings . logCount ( ) > 0 )
args < < QLatin1String ( " -m " ) < < QString : : number ( m_settings . logCount ( ) ) ;
2013-08-06 15:14:54 +03:00
if ( ! fileName . isEmpty ( ) )
args . append ( fileName ) ;
2009-12-11 16:43:39 +01:00
const PerforceResponse result = runP4Cmd ( workingDir , args ,
CommandToWindow | StdErrToWindow | ErrorToWindow ,
QStringList ( ) , QByteArray ( ) , codec ) ;
2010-01-07 11:33:30 +01:00
if ( ! result . error ) {
2014-07-28 17:47:15 +02:00
const QString source = VcsBaseEditorWidget : : getSource ( workingDir , fileName ) ;
IEditor * editor = showOutputInEditor ( tr ( " p4 filelog %1 " ) . arg ( id ) , result . stdOut ,
2012-01-07 12:31:48 +01:00
VcsBase : : LogOutput , source , codec ) ;
2010-01-07 11:33:30 +01:00
if ( enableAnnotationContextMenu )
2014-07-28 17:47:15 +02:00
VcsBaseEditorWidget : : getVcsBaseEditor ( editor ) - > setFileLogAnnotateEnabled ( true ) ;
2010-01-07 11:33:30 +01:00
}
2008-12-02 12:01:29 +01:00
}
2014-07-28 17:47:15 +02:00
void PerforcePlugin : : updateActions ( VcsBasePlugin : : ActionState as )
2008-12-02 12:01:29 +01:00
{
2010-02-12 16:03:08 +01:00
if ( ! enableMenuAction ( as , m_menuAction ) ) {
m_commandLocator - > setEnabled ( false ) ;
2012-11-28 20:28:42 +02:00
return ;
2010-02-12 16:03:08 +01:00
}
const bool hasTopLevel = currentState ( ) . hasTopLevel ( ) ;
m_commandLocator - > setEnabled ( hasTopLevel ) ;
m_logRepositoryAction - > setEnabled ( hasTopLevel ) ;
2010-01-07 11:33:30 +01:00
2009-12-11 16:43:39 +01:00
const QString fileName = currentState ( ) . currentFileName ( ) ;
m_editAction - > setParameter ( fileName ) ;
m_addAction - > setParameter ( fileName ) ;
m_deleteAction - > setParameter ( fileName ) ;
m_revertFileAction - > setParameter ( fileName ) ;
m_diffFileAction - > setParameter ( fileName ) ;
m_annotateCurrentAction - > setParameter ( fileName ) ;
m_filelogCurrentAction - > setParameter ( fileName ) ;
const QString projectName = currentState ( ) . currentProjectName ( ) ;
2010-01-07 11:33:30 +01:00
m_logProjectAction - > setParameter ( projectName ) ;
2009-12-11 16:43:39 +01:00
m_updateProjectAction - > setParameter ( projectName ) ;
m_diffProjectAction - > setParameter ( projectName ) ;
m_submitProjectAction - > setParameter ( projectName ) ;
m_revertProjectAction - > setParameter ( projectName ) ;
m_revertUnchangedAction - > setParameter ( projectName ) ;
2009-07-13 14:48:44 +02:00
2008-12-02 12:01:29 +01:00
m_diffAllAction - > setEnabled ( true ) ;
m_openedAction - > setEnabled ( true ) ;
m_describeAction - > setEnabled ( true ) ;
m_annotateAction - > setEnabled ( true ) ;
m_filelogAction - > setEnabled ( true ) ;
m_pendingAction - > setEnabled ( true ) ;
2009-07-13 14:48:44 +02:00
m_updateAllAction - > setEnabled ( true ) ;
2008-12-02 12:01:29 +01:00
}
2010-05-20 16:24:39 +02:00
bool PerforcePlugin : : managesDirectory ( const QString & directory , QString * topLevel /* = 0 */ )
{
const bool rc = managesDirectoryFstat ( directory ) ;
if ( topLevel ) {
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
if ( rc )
2010-05-20 16:24:39 +02:00
* topLevel = m_settings . topLevelSymLinkTarget ( ) ;
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
else
2010-05-20 16:24:39 +02:00
topLevel - > clear ( ) ;
}
return rc ;
}
2013-10-02 00:18:39 +03:00
bool PerforcePlugin : : managesFile ( const QString & workingDirectory , const QString & fileName ) const
{
QStringList args ;
args < < QLatin1String ( " fstat " ) < < QLatin1String ( " -m1 " ) < < fileName ;
const PerforceResponse result = runP4Cmd ( workingDirectory , args , RunFullySynchronous ) ;
return result . stdOut . contains ( QLatin1String ( " depotFile " ) ) ;
}
2010-05-20 16:24:39 +02:00
bool PerforcePlugin : : managesDirectoryFstat ( const QString & directory )
2008-12-02 12:01:29 +01:00
{
2009-12-11 16:43:39 +01:00
if ( ! m_settings . isValid ( ) )
2009-02-19 16:11:29 +01:00
return false ;
2009-12-11 16:43:39 +01:00
// Cached?
const ManagedDirectoryCache : : const_iterator cit = m_managedDirectoryCache . constFind ( directory ) ;
if ( cit ! = m_managedDirectoryCache . constEnd ( ) )
return cit . value ( ) ;
// Determine value and insert into cache
bool managed = false ;
do {
// Quick check: Must be at or below top level and not "../../other_path"
2013-08-06 15:14:54 +03:00
const QString relativeDirArgs = m_settings . relativeToTopLevelArguments ( directory ) ;
if ( ! relativeDirArgs . isEmpty ( ) & & relativeDirArgs . startsWith ( QLatin1String ( " .. " ) ) )
2009-12-11 16:43:39 +01:00
break ;
// Is it actually managed by perforce?
QStringList args ;
args < < QLatin1String ( " fstat " ) < < QLatin1String ( " -m1 " ) < < perforceRelativeFileArguments ( relativeDirArgs ) ;
const PerforceResponse result = runP4Cmd ( m_settings . topLevel ( ) , args ,
RunFullySynchronous ) ;
2012-01-31 10:57:10 +01:00
managed = result . stdOut . contains ( QLatin1String ( " depotFile " ) )
| | result . stdErr . contains ( QLatin1String ( " ... - no such file(s) " ) ) ;
2012-11-28 20:44:03 +02:00
} while ( false ) ;
2009-12-11 16:43:39 +01:00
m_managedDirectoryCache . insert ( directory , managed ) ;
return managed ;
2008-12-02 12:01:29 +01:00
}
2014-02-11 19:57:24 -05:00
bool PerforcePlugin : : vcsOpen ( const QString & workingDir , const QString & fileName , bool silently )
2008-12-02 12:01:29 +01:00
{
2009-12-11 16:43:39 +01:00
if ( Perforce : : Constants : : debug )
qDebug ( ) < < " PerforcePlugin::vcsOpen " < < workingDir < < fileName ;
QStringList args ;
args < < QLatin1String ( " edit " ) < < QDir : : toNativeSeparators ( fileName ) ;
2014-02-11 19:57:24 -05:00
int flags = CommandToWindow | StdOutToWindow | StdErrToWindow | ErrorToWindow ;
if ( silently ) {
flags | = SilentStdOut ;
}
const PerforceResponse result = runP4Cmd ( workingDir , args , flags ) ;
2008-12-02 12:01:29 +01:00
return ! result . error ;
}
2009-12-11 16:43:39 +01:00
bool PerforcePlugin : : vcsAdd ( const QString & workingDir , const QString & fileName )
2008-12-02 12:01:29 +01:00
{
2009-12-11 16:43:39 +01:00
QStringList args ;
args < < QLatin1String ( " add " ) < < fileName ;
const PerforceResponse result = runP4Cmd ( workingDir , args ,
2008-12-04 16:24:15 +01:00
CommandToWindow | StdOutToWindow | StdErrToWindow | ErrorToWindow ) ;
2008-12-02 12:01:29 +01:00
return ! result . error ;
}
2009-12-11 16:43:39 +01:00
bool PerforcePlugin : : vcsDelete ( const QString & workingDir , const QString & fileName )
2008-12-02 12:01:29 +01:00
{
2009-12-11 16:43:39 +01:00
QStringList args ;
args < < QLatin1String ( " revert " ) < < fileName ;
const PerforceResponse revertResult = runP4Cmd ( workingDir , args ,
2008-12-04 16:24:15 +01:00
CommandToWindow | StdOutToWindow | StdErrToWindow | ErrorToWindow ) ;
2009-12-11 16:43:39 +01:00
if ( revertResult . error )
return false ;
args . clear ( ) ;
args < < QLatin1String ( " delete " ) < < fileName ;
const PerforceResponse deleteResult = runP4Cmd ( workingDir , args ,
CommandToWindow | StdOutToWindow | StdErrToWindow | ErrorToWindow ) ;
2008-12-02 12:01:29 +01:00
// TODO need to carefully parse the actual messages from perforce
// or do a fstat before to decide what to do
// Different states are:
// File is in depot and unopened => p4 delete %
// File is in depot and opened => p4 revert %, p4 delete %
// File is not in depot => p4 revert %
2009-12-11 16:43:39 +01:00
return ! deleteResult . error ;
2008-12-02 12:01:29 +01:00
}
2010-05-11 14:13:38 +02:00
bool PerforcePlugin : : vcsMove ( const QString & workingDir , const QString & from , const QString & to )
{
// TODO verify this works
QStringList args ;
args < < QLatin1String ( " edit " ) < < from ;
const PerforceResponse editResult = runP4Cmd ( workingDir , args ,
2010-11-22 14:53:20 +01:00
RunFullySynchronous | CommandToWindow | StdOutToWindow | StdErrToWindow | ErrorToWindow ) ;
2010-05-11 14:13:38 +02:00
if ( editResult . error )
return false ;
args . clear ( ) ;
args < < QLatin1String ( " move " ) < < from < < to ;
const PerforceResponse moveResult = runP4Cmd ( workingDir , args ,
2010-11-22 14:53:20 +01:00
RunFullySynchronous | CommandToWindow | StdOutToWindow | StdErrToWindow | ErrorToWindow ) ;
2010-05-11 14:13:38 +02:00
return ! moveResult . error ;
}
2009-12-11 16:43:39 +01:00
// Write extra args to temporary file
2014-07-28 17:47:15 +02:00
QSharedPointer < TempFileSaver >
2013-08-02 12:54:36 +02:00
PerforcePlugin : : createTemporaryArgumentFile ( const QStringList & extraArgs ,
QString * errorString )
2008-12-02 12:01:29 +01:00
{
2009-12-11 16:43:39 +01:00
if ( extraArgs . isEmpty ( ) )
2014-07-28 17:47:15 +02:00
return QSharedPointer < TempFileSaver > ( ) ;
2009-12-11 16:43:39 +01:00
// create pattern
2013-08-02 12:54:36 +02:00
QString pattern = m_instance - > m_tempFilePattern ;
if ( pattern . isEmpty ( ) ) {
pattern = QDir : : tempPath ( ) ;
if ( ! pattern . endsWith ( QDir : : separator ( ) ) )
pattern + = QDir : : separator ( ) ;
pattern + = QLatin1String ( " qtc_p4_XXXXXX.args " ) ;
m_instance - > m_tempFilePattern = pattern ;
2008-12-02 12:01:29 +01:00
}
2014-07-28 17:47:15 +02:00
QSharedPointer < TempFileSaver > rc ( new TempFileSaver ( pattern ) ) ;
2009-12-11 16:43:39 +01:00
rc - > setAutoRemove ( true ) ;
const int last = extraArgs . size ( ) - 1 ;
for ( int i = 0 ; i < = last ; i + + ) {
rc - > write ( extraArgs . at ( i ) . toLocal8Bit ( ) ) ;
if ( i ! = last )
2011-03-30 15:15:15 +02:00
rc - > write ( " \n " , 1 ) ;
2009-12-11 16:43:39 +01:00
}
2011-03-30 15:15:15 +02:00
if ( ! rc - > finalize ( errorString ) )
2014-07-28 17:47:15 +02:00
return QSharedPointer < TempFileSaver > ( ) ;
2009-12-11 16:43:39 +01:00
return rc ;
}
2008-12-02 12:01:29 +01:00
2009-12-11 16:43:39 +01:00
// Run messages
static inline QString msgNotStarted ( const QString & cmd )
{
2014-04-17 14:09:47 +02:00
return PerforcePlugin : : tr ( " Could not start perforce \" %1 \" . Please check your settings in the preferences. " ) . arg ( cmd ) ;
2009-12-11 16:43:39 +01:00
}
2009-12-14 09:41:38 +01:00
static inline QString msgTimeout ( int timeOut )
2009-12-11 16:43:39 +01:00
{
2009-12-14 09:41:38 +01:00
return PerforcePlugin : : tr ( " Perforce did not respond within timeout limit (%1 ms). " ) . arg ( timeOut ) ;
2009-12-11 16:43:39 +01:00
}
static inline QString msgCrash ( )
{
return PerforcePlugin : : tr ( " The process terminated abnormally. " ) ;
}
static inline QString msgExitCode ( int ex )
{
return PerforcePlugin : : tr ( " The process terminated with exit code %1. " ) . arg ( ex ) ;
}
// Run using a SynchronousProcess, emitting signals to the message window
PerforceResponse PerforcePlugin : : synchronousProcess ( const QString & workingDir ,
const QStringList & args ,
unsigned flags ,
const QByteArray & stdInput ,
2013-08-02 12:54:36 +02:00
QTextCodec * outputCodec )
2009-12-11 16:43:39 +01:00
{
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( stdInput . isEmpty ( ) , return PerforceResponse ( ) ) ; // Not supported here
2008-12-02 12:01:29 +01:00
2014-08-26 00:02:47 +02:00
VcsOutputWindow * outputWindow = VcsOutputWindow : : instance ( ) ;
2008-12-02 12:01:29 +01:00
// Run, connect stderr to the output window
2014-07-28 17:47:15 +02:00
SynchronousProcess process ;
2013-08-02 12:54:36 +02:00
const int timeOut = ( flags & LongTimeOut ) ? settings ( ) . longTimeOutMS ( ) : settings ( ) . timeOutMS ( ) ;
2009-12-14 09:41:38 +01:00
process . setTimeout ( timeOut ) ;
2013-07-01 22:27:44 +03:00
process . setCodec ( outputCodec ) ;
2009-12-11 16:43:39 +01:00
if ( flags & OverrideDiffEnvironment )
process . setProcessEnvironment ( overrideDiffEnvironmentVariable ( ) ) ;
if ( ! workingDir . isEmpty ( ) )
process . setWorkingDirectory ( workingDir ) ;
2008-12-02 12:01:29 +01:00
// connect stderr to the output window if desired
2009-12-11 16:43:39 +01:00
if ( flags & StdErrToWindow ) {
2008-12-02 12:01:29 +01:00
process . setStdErrBufferedSignalsEnabled ( true ) ;
2009-08-10 15:46:45 +02:00
connect ( & process , SIGNAL ( stdErrBuffered ( QString , bool ) ) , outputWindow , SLOT ( append ( QString ) ) ) ;
2008-12-02 12:01:29 +01:00
}
// connect stdout to the output window if desired
2009-12-11 16:43:39 +01:00
if ( flags & StdOutToWindow ) {
2008-12-02 12:01:29 +01:00
process . setStdOutBufferedSignalsEnabled ( true ) ;
2014-02-11 19:57:24 -05:00
if ( flags & SilentStdOut ) {
connect ( & process , SIGNAL ( stdOutBuffered ( QString , bool ) ) , outputWindow , SLOT ( appendSilently ( QString ) ) ) ;
}
else {
connect ( & process , SIGNAL ( stdOutBuffered ( QString , bool ) ) , outputWindow , SLOT ( append ( QString ) ) ) ;
}
2008-12-02 12:01:29 +01:00
}
2009-12-11 16:43:39 +01:00
if ( Perforce : : Constants : : debug )
qDebug ( ) < < " PerforcePlugin::run syncp actual args [ " < < process . workingDirectory ( ) < < ' ] ' < < args ;
2010-05-21 17:46:00 +02:00
process . setTimeOutMessageBoxEnabled ( true ) ;
2014-07-28 17:47:15 +02:00
const SynchronousProcessResponse sp_resp = process . run ( settings ( ) . p4BinaryPath ( ) , args ) ;
2008-12-02 12:01:29 +01:00
if ( Perforce : : Constants : : debug )
qDebug ( ) < < sp_resp ;
2009-12-11 16:43:39 +01:00
PerforceResponse response ;
2008-12-02 12:01:29 +01:00
response . error = true ;
2009-12-11 16:43:39 +01:00
response . exitCode = sp_resp . exitCode ;
2008-12-02 12:01:29 +01:00
response . stdErr = sp_resp . stdErr ;
response . stdOut = sp_resp . stdOut ;
switch ( sp_resp . result ) {
2014-07-28 17:47:15 +02:00
case SynchronousProcessResponse : : Finished :
2008-12-02 12:01:29 +01:00
response . error = false ;
break ;
2014-07-28 17:47:15 +02:00
case SynchronousProcessResponse : : FinishedError :
2009-12-11 16:43:39 +01:00
response . message = msgExitCode ( sp_resp . exitCode ) ;
response . error = ! ( flags & IgnoreExitCode ) ;
2008-12-02 12:01:29 +01:00
break ;
2014-07-28 17:47:15 +02:00
case SynchronousProcessResponse : : TerminatedAbnormally :
2009-12-11 16:43:39 +01:00
response . message = msgCrash ( ) ;
2008-12-02 12:01:29 +01:00
break ;
2014-07-28 17:47:15 +02:00
case SynchronousProcessResponse : : StartFailed :
2013-08-02 12:54:36 +02:00
response . message = msgNotStarted ( settings ( ) . p4BinaryPath ( ) ) ;
2008-12-02 12:01:29 +01:00
break ;
2014-07-28 17:47:15 +02:00
case SynchronousProcessResponse : : Hang :
2009-12-11 16:43:39 +01:00
response . message = msgCrash ( ) ;
2008-12-02 12:01:29 +01:00
break ;
}
2009-12-11 16:43:39 +01:00
return response ;
}
// Run using a QProcess, for short queries
PerforceResponse PerforcePlugin : : fullySynchronousProcess ( const QString & workingDir ,
const QStringList & args ,
unsigned flags ,
const QByteArray & stdInput ,
2013-08-02 12:54:36 +02:00
QTextCodec * outputCodec )
2009-12-11 16:43:39 +01:00
{
QProcess process ;
if ( flags & OverrideDiffEnvironment )
process . setProcessEnvironment ( overrideDiffEnvironmentVariable ( ) ) ;
if ( ! workingDir . isEmpty ( ) )
process . setWorkingDirectory ( workingDir ) ;
if ( Perforce : : Constants : : debug )
qDebug ( ) < < " PerforcePlugin::run fully syncp actual args [ " < < process . workingDirectory ( ) < < ' ] ' < < args ;
PerforceResponse response ;
2013-08-02 12:54:36 +02:00
process . start ( settings ( ) . p4BinaryPath ( ) , args ) ;
2009-12-11 16:43:39 +01:00
if ( stdInput . isEmpty ( ) )
process . closeWriteChannel ( ) ;
if ( ! process . waitForStarted ( 3000 ) ) {
response . error = true ;
2013-08-02 12:54:36 +02:00
response . message = msgNotStarted ( settings ( ) . p4BinaryPath ( ) ) ;
2009-12-11 16:43:39 +01:00
return response ;
}
if ( ! stdInput . isEmpty ( ) ) {
if ( process . write ( stdInput ) = = - 1 ) {
2014-07-28 17:47:15 +02:00
SynchronousProcess : : stopProcess ( process ) ;
2009-12-11 16:43:39 +01:00
response . error = true ;
2010-07-05 09:52:32 +02:00
response . message = tr ( " Unable to write input data to process %1: %2 " ) .
2013-08-02 12:54:36 +02:00
arg ( QDir : : toNativeSeparators ( settings ( ) . p4BinaryPath ( ) ) ,
2010-07-05 09:52:32 +02:00
process . errorString ( ) ) ;
2009-12-11 16:43:39 +01:00
return response ;
}
process . closeWriteChannel ( ) ;
}
2010-03-01 10:06:05 +01:00
QByteArray stdOut ;
QByteArray stdErr ;
2013-08-02 12:54:36 +02:00
const int timeOut = ( flags & LongTimeOut ) ? settings ( ) . longTimeOutMS ( ) : settings ( ) . timeOutMS ( ) ;
2014-07-28 17:47:15 +02:00
if ( ! SynchronousProcess : : readDataFromProcess ( process , timeOut , & stdOut , & stdErr , true ) ) {
SynchronousProcess : : stopProcess ( process ) ;
2009-12-11 16:43:39 +01:00
response . error = true ;
2009-12-14 09:41:38 +01:00
response . message = msgTimeout ( timeOut ) ;
2009-12-11 16:43:39 +01:00
return response ;
}
if ( process . exitStatus ( ) ! = QProcess : : NormalExit ) {
response . error = true ;
response . message = msgCrash ( ) ;
return response ;
}
response . exitCode = process . exitCode ( ) ;
response . error = response . exitCode ? ! ( flags & IgnoreExitCode ) : false ;
2010-03-01 10:06:05 +01:00
response . stdErr = QString : : fromLocal8Bit ( stdErr ) ;
2009-12-11 16:43:39 +01:00
response . stdOut = outputCodec ? outputCodec - > toUnicode ( stdOut . constData ( ) , stdOut . size ( ) ) :
QString : : fromLocal8Bit ( stdOut ) ;
2009-12-11 17:04:13 +01:00
const QChar cr = QLatin1Char ( ' \r ' ) ;
response . stdErr . remove ( cr ) ;
response . stdOut . remove ( cr ) ;
2009-12-11 16:43:39 +01:00
// Logging
if ( ( flags & StdErrToWindow ) & & ! response . stdErr . isEmpty ( ) )
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : appendError ( response . stdErr ) ;
2009-12-11 16:43:39 +01:00
if ( ( flags & StdOutToWindow ) & & ! response . stdOut . isEmpty ( ) )
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : append ( response . stdOut , VcsOutputWindow : : None , flags & SilentStdOut ) ;
2009-12-11 16:43:39 +01:00
return response ;
}
PerforceResponse PerforcePlugin : : runP4Cmd ( const QString & workingDir ,
const QStringList & args ,
unsigned flags ,
const QStringList & extraArgs ,
const QByteArray & stdInput ,
2013-08-02 12:54:36 +02:00
QTextCodec * outputCodec )
2009-12-11 16:43:39 +01:00
{
if ( Perforce : : Constants : : debug )
qDebug ( ) < < " PerforcePlugin::runP4Cmd [ " < < workingDir < < ' ] ' < < args < < extraArgs < < stdInput < < debugCodec ( outputCodec ) ;
2013-08-02 12:54:36 +02:00
if ( ! settings ( ) . isValid ( ) ) {
2009-12-11 16:43:39 +01:00
PerforceResponse invalidConfigResponse ;
invalidConfigResponse . error = true ;
invalidConfigResponse . message = tr ( " Perforce is not correctly configured. " ) ;
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : appendError ( invalidConfigResponse . message ) ;
2009-12-11 16:43:39 +01:00
return invalidConfigResponse ;
}
2013-08-02 12:54:36 +02:00
QStringList actualArgs = settings ( ) . commonP4Arguments ( workingDir ) ;
2011-03-30 15:15:15 +02:00
QString errorMessage ;
2014-07-28 17:47:15 +02:00
QSharedPointer < TempFileSaver > tempFile = createTemporaryArgumentFile ( extraArgs , & errorMessage ) ;
2011-03-30 15:15:15 +02:00
if ( ! tempFile . isNull ( ) ) {
2009-12-11 16:43:39 +01:00
actualArgs < < QLatin1String ( " -x " ) < < tempFile - > fileName ( ) ;
2011-03-30 15:15:15 +02:00
} else if ( ! errorMessage . isEmpty ( ) ) {
PerforceResponse tempFailResponse ;
tempFailResponse . error = true ;
tempFailResponse . message = errorMessage ;
return tempFailResponse ;
}
2009-12-11 16:43:39 +01:00
actualArgs . append ( args ) ;
2014-07-28 17:47:15 +02:00
if ( flags & CommandToWindow )
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : appendCommand ( workingDir , FileName : : fromString ( settings ( ) . p4BinaryPath ( ) ) , actualArgs ) ;
2009-12-11 16:43:39 +01:00
if ( flags & ShowBusyCursor )
QApplication : : setOverrideCursor ( QCursor ( Qt : : WaitCursor ) ) ;
const PerforceResponse response = ( flags & RunFullySynchronous ) ?
fullySynchronousProcess ( workingDir , actualArgs , flags , stdInput , outputCodec ) :
synchronousProcess ( workingDir , actualArgs , flags , stdInput , outputCodec ) ;
if ( flags & ShowBusyCursor )
QApplication : : restoreOverrideCursor ( ) ;
2008-12-04 16:24:15 +01:00
if ( response . error ) {
if ( Perforce : : Constants : : debug )
qDebug ( ) < < response . message ;
2009-12-11 16:43:39 +01:00
if ( flags & ErrorToWindow )
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : appendError ( response . message ) ;
2008-12-04 16:24:15 +01:00
}
2008-12-02 12:01:29 +01:00
return response ;
}
2014-07-28 17:47:15 +02:00
IEditor * PerforcePlugin : : showOutputInEditor ( const QString & title ,
const QString & output ,
int editorType ,
const QString & source ,
QTextCodec * codec )
2008-12-02 12:01:29 +01:00
{
2014-07-28 17:47:15 +02:00
const VcsBaseEditorParameters * params = findType ( editorType ) ;
2008-12-09 15:25:01 +01:00
QTC_ASSERT ( params , return 0 ) ;
2014-07-28 17:47:15 +02:00
const Id id = params - > id ;
2008-12-02 12:01:29 +01:00
if ( Perforce : : Constants : : debug )
2011-11-10 11:36:51 +01:00
qDebug ( ) < < " PerforcePlugin::showOutputInEditor " < < title < < id . name ( )
< < " Size= " < < output . size ( ) < < " Type= " < < editorType < < debugCodec ( codec ) ;
2008-12-02 12:01:29 +01:00
QString s = title ;
2014-07-28 17:47:15 +02:00
IEditor * editor = EditorManager : : openEditorWithContents ( id , & s , output . toUtf8 ( ) ) ;
2013-10-06 20:47:29 +03:00
connect ( editor , SIGNAL ( annotateRevisionRequested ( QString , QString , QString , int ) ) ,
this , SLOT ( vcsAnnotate ( QString , QString , QString , int ) ) ) ;
2014-08-21 20:43:33 +02:00
PerforceEditorWidget * e = qobject_cast < PerforceEditorWidget * > ( editor - > widget ( ) ) ;
2008-12-02 12:01:29 +01:00
if ( ! e )
return 0 ;
2010-06-07 14:53:28 +02:00
e - > setForceReadOnly ( true ) ;
2010-01-06 17:24:40 +01:00
e - > setSource ( source ) ;
2008-12-02 12:01:29 +01:00
s . replace ( QLatin1Char ( ' ' ) , QLatin1Char ( ' _ ' ) ) ;
2014-08-01 23:31:56 +02:00
e - > textDocument ( ) - > setSuggestedFileName ( s ) ;
2008-12-02 12:01:29 +01:00
if ( codec )
e - > setCodec ( codec ) ;
2013-12-19 10:22:02 +01:00
return editor ;
2008-12-02 12:01:29 +01:00
}
2009-12-11 16:43:39 +01:00
void PerforcePlugin : : slotSubmitDiff ( const QStringList & files )
2008-12-02 12:01:29 +01:00
{
2009-12-11 16:43:39 +01:00
p4Diff ( m_commitWorkingDirectory , files ) ;
2008-12-02 12:01:29 +01:00
}
2011-03-31 10:57:33 +02:00
struct PerforceDiffParameters
2008-12-02 12:01:29 +01:00
{
2011-03-31 10:57:33 +02:00
QString workingDir ;
QStringList diffArguments ;
QStringList files ;
} ;
2008-12-02 12:01:29 +01:00
2011-03-31 10:57:33 +02:00
// Parameter widget controlling whitespace diff mode, associated with a parameter
2014-07-28 17:47:15 +02:00
class PerforceDiffParameterWidget : public VcsBaseEditorParameterWidget
2011-03-31 10:57:33 +02:00
{
Q_OBJECT
public :
explicit PerforceDiffParameterWidget ( const PerforceDiffParameters & p , QWidget * parent = 0 ) ;
signals :
void reRunDiff ( const Perforce : : Internal : : PerforceDiffParameters & ) ;
private slots :
void triggerReRun ( ) ;
private :
const PerforceDiffParameters m_parameters ;
} ;
PerforceDiffParameterWidget : : PerforceDiffParameterWidget ( const PerforceDiffParameters & p , QWidget * parent ) :
2014-07-28 17:47:15 +02:00
VcsBaseEditorParameterWidget ( parent ) , m_parameters ( p )
2011-03-31 10:57:33 +02:00
{
setBaseArguments ( p . diffArguments ) ;
2013-10-10 10:37:15 +02:00
addToggleButton ( QLatin1String ( " w " ) , tr ( " Ignore Whitespace " ) ) ;
2011-03-31 10:57:33 +02:00
connect ( this , SIGNAL ( argumentsChanged ( ) ) , this , SLOT ( triggerReRun ( ) ) ) ;
}
void PerforceDiffParameterWidget : : triggerReRun ( )
{
PerforceDiffParameters effectiveParameters = m_parameters ;
effectiveParameters . diffArguments = arguments ( ) ;
emit reRunDiff ( effectiveParameters ) ;
}
2009-12-11 16:43:39 +01:00
2011-03-31 10:57:33 +02:00
void PerforcePlugin : : p4Diff ( const QString & workingDir , const QStringList & files )
{
PerforceDiffParameters p ;
p . workingDir = workingDir ;
p . files = files ;
p . diffArguments . push_back ( QString ( QLatin1Char ( ' u ' ) ) ) ;
p4Diff ( p ) ;
}
void PerforcePlugin : : p4Diff ( const PerforceDiffParameters & p )
{
2014-07-28 17:47:15 +02:00
QTextCodec * codec = VcsBaseEditorWidget : : getCodec ( p . workingDir , p . files ) ;
const QString id = VcsBaseEditorWidget : : getTitleId ( p . workingDir , p . files ) ;
2009-12-11 16:43:39 +01:00
// Reuse existing editors for that id
2014-07-28 17:47:15 +02:00
const QString tag = VcsBaseEditorWidget : : editorTag ( VcsBase : : DiffOutput , p . workingDir , p . files ) ;
IEditor * existingEditor = VcsBaseEditorWidget : : locateEditorByTag ( tag ) ;
2009-12-11 16:43:39 +01:00
// Split arguments according to size
QStringList args ;
2011-03-31 10:57:33 +02:00
args < < QLatin1String ( " diff " ) ;
if ( ! p . diffArguments . isEmpty ( ) ) // -duw..
args < < ( QLatin1String ( " -d " ) + p . diffArguments . join ( QString ( ) ) ) ;
2009-12-11 16:43:39 +01:00
QStringList extraArgs ;
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
if ( p . files . size ( ) > 1 )
2011-03-31 10:57:33 +02:00
extraArgs = p . files ;
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
else
2011-03-31 10:57:33 +02:00
args . append ( p . files ) ;
2009-12-11 16:43:39 +01:00
const unsigned flags = CommandToWindow | StdErrToWindow | ErrorToWindow | OverrideDiffEnvironment ;
2011-03-31 10:57:33 +02:00
const PerforceResponse result = runP4Cmd ( p . workingDir , args , flags ,
2009-12-11 16:43:39 +01:00
extraArgs , QByteArray ( ) , codec ) ;
2008-12-02 12:01:29 +01:00
if ( result . error )
return ;
2009-12-11 16:43:39 +01:00
if ( existingEditor ) {
2013-07-15 15:14:10 +02:00
existingEditor - > document ( ) - > setContents ( result . stdOut . toUtf8 ( ) ) ;
2014-07-28 17:47:15 +02:00
EditorManager : : activateEditor ( existingEditor ) ;
2011-03-31 10:57:33 +02:00
return ;
2008-12-02 12:01:29 +01:00
}
2011-03-31 10:57:33 +02:00
// Create new editor
2014-07-28 17:47:15 +02:00
IEditor * editor = showOutputInEditor ( tr ( " p4 diff %1 " ) . arg ( id ) , result . stdOut , VcsBase : : DiffOutput ,
VcsBaseEditorWidget : : getSource ( p . workingDir , p . files ) ,
codec ) ;
VcsBaseEditorWidget : : tagEditor ( editor , tag ) ;
VcsBaseEditorWidget * diffEditorWidget = qobject_cast < VcsBaseEditorWidget * > ( editor - > widget ( ) ) ;
2011-03-31 10:57:33 +02:00
// Wire up the parameter widget to trigger a re-run on
// parameter change and 'revert' from inside the diff editor.
PerforceDiffParameterWidget * pw = new PerforceDiffParameterWidget ( p ) ;
connect ( pw , SIGNAL ( reRunDiff ( Perforce : : Internal : : PerforceDiffParameters ) ) ,
this , SLOT ( p4Diff ( Perforce : : Internal : : PerforceDiffParameters ) ) ) ;
2012-01-07 12:31:48 +01:00
connect ( diffEditorWidget , SIGNAL ( diffChunkReverted ( VcsBase : : DiffChunk ) ) ,
2011-03-31 10:57:33 +02:00
pw , SLOT ( triggerReRun ( ) ) ) ;
diffEditorWidget - > setConfigurationWidget ( pw ) ;
2008-12-02 12:01:29 +01:00
}
void PerforcePlugin : : describe ( const QString & source , const QString & n )
{
2014-07-28 17:47:15 +02:00
QTextCodec * codec = source . isEmpty ( ) ? static_cast < QTextCodec * > ( 0 ) : VcsBaseEditorWidget : : getCodec ( source ) ;
2008-12-02 12:01:29 +01:00
QStringList args ;
args < < QLatin1String ( " describe " ) < < QLatin1String ( " -du " ) < < n ;
2009-12-11 16:43:39 +01:00
const PerforceResponse result = runP4Cmd ( m_settings . topLevel ( ) , args , CommandToWindow | StdErrToWindow | ErrorToWindow ,
QStringList ( ) , QByteArray ( ) , codec ) ;
2008-12-02 12:01:29 +01:00
if ( ! result . error )
2012-01-07 12:31:48 +01:00
showOutputInEditor ( tr ( " p4 describe %1 " ) . arg ( n ) , result . stdOut , VcsBase : : DiffOutput , source , codec ) ;
2008-12-02 12:01:29 +01:00
}
void PerforcePlugin : : submitCurrentLog ( )
{
2009-03-20 10:16:18 +01:00
m_submitActionTriggered = true ;
2014-08-19 16:15:57 +02:00
QTC_ASSERT ( submitEditor ( ) , return ) ;
EditorManager : : closeDocument ( submitEditor ( ) - > document ( ) ) ;
2008-12-02 12:01:29 +01:00
}
2009-09-22 12:23:44 +02:00
void PerforcePlugin : : cleanCommitMessageFile ( )
2009-03-20 16:52:22 +01:00
{
2009-09-22 12:23:44 +02:00
if ( ! m_commitMessageFileName . isEmpty ( ) ) {
QFile : : remove ( m_commitMessageFileName ) ;
m_commitMessageFileName . clear ( ) ;
2009-12-11 16:43:39 +01:00
m_commitWorkingDirectory . clear ( ) ;
2009-03-20 16:52:22 +01:00
}
}
2009-09-22 12:23:44 +02:00
bool PerforcePlugin : : isCommitEditorOpen ( ) const
{
return ! m_commitMessageFileName . isEmpty ( ) ;
}
2013-04-18 12:06:43 +02:00
bool PerforcePlugin : : submitEditorAboutToClose ( )
2008-12-02 12:01:29 +01:00
{
2009-12-08 14:26:41 +01:00
if ( ! isCommitEditorOpen ( ) )
2008-12-02 12:01:29 +01:00
return true ;
2013-04-18 12:06:43 +02:00
PerforceSubmitEditor * perforceEditor = qobject_cast < PerforceSubmitEditor * > ( submitEditor ( ) ) ;
QTC_ASSERT ( perforceEditor , return true ) ;
2014-07-28 17:47:15 +02:00
IDocument * editorDocument = perforceEditor - > document ( ) ;
2013-04-18 12:06:43 +02:00
QTC_ASSERT ( editorDocument , return true ) ;
2009-12-11 16:43:39 +01:00
// Prompt the user. Force a prompt unless submit was actually invoked (that
// is, the editor was closed or shutdown).
bool wantsPrompt = m_settings . promptToSubmit ( ) ;
2014-07-28 17:47:15 +02:00
const VcsBaseSubmitEditor : : PromptSubmitResult answer =
2009-03-19 17:40:01 +01:00
perforceEditor - > promptSubmit ( tr ( " Closing p4 Editor " ) ,
tr ( " Do you want to submit this change list? " ) ,
2011-06-21 17:07:45 +02:00
tr ( " The commit message check failed. Do you want to submit this change list? " ) ,
2009-06-19 16:34:38 +02:00
& wantsPrompt , ! m_submitActionTriggered ) ;
2009-12-11 16:43:39 +01:00
m_submitActionTriggered = false ;
2009-03-19 17:40:01 +01:00
2014-07-28 17:47:15 +02:00
if ( answer = = VcsBaseSubmitEditor : : SubmitCanceled )
2009-12-11 16:43:39 +01:00
return false ;
2008-12-02 12:01:29 +01:00
2009-12-11 16:43:39 +01:00
// Set without triggering the checking mechanism
if ( wantsPrompt ! = m_settings . promptToSubmit ( ) ) {
m_settings . setPromptToSubmit ( wantsPrompt ) ;
2014-07-28 17:47:15 +02:00
m_settings . toSettings ( ICore : : settings ( ) ) ;
2009-12-11 16:43:39 +01:00
}
2014-07-28 17:47:15 +02:00
if ( ! DocumentManager : : saveDocument ( editorDocument ) )
2011-03-30 12:43:17 +02:00
return false ;
2014-07-28 17:47:15 +02:00
if ( answer = = VcsBaseSubmitEditor : : SubmitDiscarded ) {
2009-09-22 12:23:44 +02:00
cleanCommitMessageFile ( ) ;
2009-12-11 16:43:39 +01:00
return true ;
}
// Pipe file into p4 submit -i
2014-07-28 17:47:15 +02:00
FileReader reader ;
2011-03-30 15:15:15 +02:00
if ( ! reader . fetch ( m_commitMessageFileName , QIODevice : : Text ) ) {
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : appendError ( reader . errorString ( ) ) ;
2009-12-11 16:43:39 +01:00
return false ;
2008-12-02 12:01:29 +01:00
}
2009-12-11 16:43:39 +01:00
QStringList submitArgs ;
submitArgs < < QLatin1String ( " submit " ) < < QLatin1String ( " -i " ) ;
const PerforceResponse submitResponse = runP4Cmd ( m_settings . topLevelSymLinkTarget ( ) , submitArgs ,
2009-12-14 09:41:38 +01:00
LongTimeOut | RunFullySynchronous | CommandToWindow | StdErrToWindow | ErrorToWindow | ShowBusyCursor ,
2011-03-30 15:15:15 +02:00
QStringList ( ) , reader . data ( ) ) ;
2009-12-11 16:43:39 +01:00
if ( submitResponse . error ) {
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : appendError ( tr ( " p4 submit failed: %1 " ) . arg ( submitResponse . message ) ) ;
2009-12-11 16:43:39 +01:00
return false ;
}
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : append ( submitResponse . stdOut ) ;
2009-12-11 16:43:39 +01:00
if ( submitResponse . stdOut . contains ( QLatin1String ( " Out of date files must be resolved or reverted) " ) ) )
2013-04-18 12:06:43 +02:00
QMessageBox : : warning ( perforceEditor - > widget ( ) , tr ( " Pending change " ) , tr ( " Could not submit the change, because your workspace was out of date. Created a pending submit instead. " ) ) ;
2009-12-11 16:43:39 +01:00
cleanCommitMessageFile ( ) ;
return true ;
2008-12-02 12:01:29 +01:00
}
QString PerforcePlugin : : clientFilePath ( const QString & serverFilePath )
{
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( m_settings . isValid ( ) , return QString ( ) ) ;
2008-12-02 12:01:29 +01:00
2009-12-11 16:43:39 +01:00
QStringList args ;
args < < QLatin1String ( " fstat " ) < < serverFilePath ;
const PerforceResponse response = runP4Cmd ( m_settings . topLevelSymLinkTarget ( ) , args ,
ShowBusyCursor | RunFullySynchronous | CommandToWindow | StdErrToWindow | ErrorToWindow ) ;
if ( response . error )
2010-02-02 17:09:41 +01:00
return QString ( ) ;
2009-12-11 16:43:39 +01:00
QRegExp r ( QLatin1String ( " \\ . \\ . \\ . \\ sclientFile \\ s(.+) \ n " )) ;
r . setMinimal ( true ) ;
const QString path = r . indexIn ( response . stdOut ) ! = - 1 ? r . cap ( 1 ) . trimmed ( ) : QString ( ) ;
if ( Perforce : : Constants : : debug )
qDebug ( ) < < " clientFilePath " < < serverFilePath < < path ;
2008-12-02 12:01:29 +01:00
return path ;
}
2009-12-11 16:43:39 +01:00
QString PerforcePlugin : : pendingChangesData ( )
2008-12-02 12:01:29 +01:00
{
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( m_settings . isValid ( ) , return QString ( ) ) ;
2008-12-02 12:01:29 +01:00
2009-12-11 16:43:39 +01:00
QStringList args = QStringList ( QLatin1String ( " info " ) ) ;
const PerforceResponse userResponse = runP4Cmd ( m_settings . topLevelSymLinkTarget ( ) , args ,
RunFullySynchronous | CommandToWindow | StdErrToWindow | ErrorToWindow ) ;
if ( userResponse . error )
2010-02-02 17:09:41 +01:00
return QString ( ) ;
2008-12-02 12:01:29 +01:00
2009-12-11 16:43:39 +01:00
QRegExp r ( QLatin1String ( " User \\ sname: \\ s( \\ S+) \ \ s * \ n " )) ;
2012-04-17 08:01:25 +02:00
QTC_ASSERT ( r . isValid ( ) , return QString ( ) ) ;
2009-12-11 16:43:39 +01:00
r . setMinimal ( true ) ;
2010-02-02 17:09:41 +01:00
const QString user = r . indexIn ( userResponse . stdOut ) ! = - 1 ? r . cap ( 1 ) . trimmed ( ) : QString ( ) ;
2008-12-02 12:01:29 +01:00
if ( user . isEmpty ( ) )
2010-02-02 17:09:41 +01:00
return QString ( ) ;
2009-12-11 16:43:39 +01:00
args . clear ( ) ;
args < < QLatin1String ( " changes " ) < < QLatin1String ( " -s " ) < < QLatin1String ( " pending " ) < < QLatin1String ( " -u " ) < < user ;
const PerforceResponse dataResponse = runP4Cmd ( m_settings . topLevelSymLinkTarget ( ) , args ,
RunFullySynchronous | CommandToWindow | StdErrToWindow | ErrorToWindow ) ;
2010-02-02 17:09:41 +01:00
return dataResponse . error ? QString ( ) : dataResponse . stdOut ;
2008-12-02 12:01:29 +01:00
}
PerforcePlugin : : ~ PerforcePlugin ( )
{
}
2013-08-02 12:54:36 +02:00
const PerforceSettings & PerforcePlugin : : settings ( )
2008-12-02 12:01:29 +01:00
{
2013-08-02 12:54:36 +02:00
return m_instance - > m_settings ;
2008-12-02 12:01:29 +01:00
}
2009-05-28 10:30:10 +02:00
void PerforcePlugin : : setSettings ( const Settings & newSettings )
2008-12-02 12:01:29 +01:00
{
2013-08-02 12:54:36 +02:00
if ( newSettings ! = m_instance - > m_settings . settings ( ) ) {
m_instance - > m_settings . setSettings ( newSettings ) ;
m_instance - > m_managedDirectoryCache . clear ( ) ;
2014-07-28 17:47:15 +02:00
m_instance - > m_settings . toSettings ( ICore : : settings ( ) ) ;
2009-12-11 16:43:39 +01:00
getTopLevel ( ) ;
2011-04-15 17:43:44 +02:00
perforceVersionControl ( ) - > emitConfigurationChanged ( ) ;
2008-12-02 12:01:29 +01:00
}
}
2009-12-11 16:43:39 +01:00
static inline QString msgWhereFailed ( const QString & file , const QString & why )
{
2010-02-25 14:52:20 +01:00
//: Failed to run p4 "where" to resolve a Perforce file name to a local
//: file system name.
2010-07-05 09:52:32 +02:00
return PerforcePlugin : : tr ( " Error running \" where \" on %1: %2 " ) .
arg ( QDir : : toNativeSeparators ( file ) , why ) ;
2009-12-11 16:43:39 +01:00
}
2008-12-02 12:01:29 +01:00
// Map a perforce name "//xx" to its real name in the file system
QString PerforcePlugin : : fileNameFromPerforceName ( const QString & perforceName ,
2009-12-15 14:20:06 +01:00
bool quiet ,
2013-08-02 12:54:36 +02:00
QString * errorMessage )
2008-12-02 12:01:29 +01:00
{
// All happy, already mapped
if ( ! perforceName . startsWith ( QLatin1String ( " // " ) ) )
return perforceName ;
// "where" remaps the file to client file tree
2009-12-11 16:43:39 +01:00
QStringList args ;
2008-12-02 12:01:29 +01:00
args < < QLatin1String ( " where " ) < < perforceName ;
2009-12-15 14:20:06 +01:00
unsigned flags = RunFullySynchronous ;
if ( ! quiet )
flags | = CommandToWindow | StdErrToWindow | ErrorToWindow ;
2013-08-02 12:54:36 +02:00
const PerforceResponse response = runP4Cmd ( settings ( ) . topLevelSymLinkTarget ( ) , args , flags ) ;
2009-12-11 16:43:39 +01:00
if ( response . error ) {
* errorMessage = msgWhereFailed ( perforceName , response . message ) ;
2011-02-25 15:27:13 +01:00
return QString ( ) ;
2008-12-02 12:01:29 +01:00
}
2009-12-11 16:43:39 +01:00
QString output = response . stdOut ;
2008-12-02 12:01:29 +01:00
if ( output . endsWith ( QLatin1Char ( ' \r ' ) ) )
output . chop ( 1 ) ;
if ( output . endsWith ( QLatin1Char ( ' \n ' ) ) )
output . chop ( 1 ) ;
if ( output . isEmpty ( ) ) {
2010-02-25 14:52:20 +01:00
//: File is not managed by Perforce
2009-12-11 16:43:39 +01:00
* errorMessage = msgWhereFailed ( perforceName , tr ( " The file is not mapped " ) ) ;
2008-12-02 12:01:29 +01:00
return QString ( ) ;
}
2009-12-11 16:43:39 +01:00
const QString p4fileSpec = output . mid ( output . lastIndexOf ( QLatin1Char ( ' ' ) ) + 1 ) ;
2013-08-02 12:54:36 +02:00
const QString rc = m_instance - > m_settings . mapToFileSystem ( p4fileSpec ) ;
2008-12-02 12:01:29 +01:00
if ( Perforce : : Constants : : debug )
2009-12-11 16:43:39 +01:00
qDebug ( ) < < " fileNameFromPerforceName " < < perforceName < < p4fileSpec < < rc ;
2008-12-02 12:01:29 +01:00
return rc ;
}
2013-08-02 12:54:36 +02:00
PerforceVersionControl * PerforcePlugin : : perforceVersionControl ( )
2009-12-08 14:26:41 +01:00
{
2013-08-02 12:54:36 +02:00
return static_cast < PerforceVersionControl * > ( m_instance - > versionControl ( ) ) ;
2009-12-08 14:26:41 +01:00
}
2009-12-11 16:43:39 +01:00
void PerforcePlugin : : slotTopLevelFound ( const QString & t )
{
m_settings . setTopLevel ( t ) ;
2010-07-05 09:52:32 +02:00
const QString msg = tr ( " Perforce repository: %1 " ) .
arg ( QDir : : toNativeSeparators ( t ) ) ;
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : appendSilently ( msg ) ;
2009-12-11 16:43:39 +01:00
if ( Perforce : : Constants : : debug )
qDebug ( ) < < " P4: " < < t ;
}
void PerforcePlugin : : slotTopLevelFailed ( const QString & errorMessage )
{
2014-08-26 00:02:47 +02:00
VcsOutputWindow : : appendSilently ( tr ( " Perforce: Unable to determine the repository: %1 " ) . arg ( errorMessage ) ) ;
2009-12-11 16:43:39 +01:00
if ( Perforce : : Constants : : debug )
qDebug ( ) < < errorMessage ;
}
void PerforcePlugin : : getTopLevel ( )
{
// Run a new checker
2013-08-02 12:54:36 +02:00
if ( m_instance - > m_settings . p4BinaryPath ( ) . isEmpty ( ) )
2009-12-11 16:43:39 +01:00
return ;
2013-08-02 12:54:36 +02:00
PerforceChecker * checker = new PerforceChecker ( m_instance ) ;
connect ( checker , SIGNAL ( failed ( QString ) ) , m_instance , SLOT ( slotTopLevelFailed ( QString ) ) ) ;
2009-12-11 16:43:39 +01:00
connect ( checker , SIGNAL ( failed ( QString ) ) , checker , SLOT ( deleteLater ( ) ) ) ;
2013-08-02 12:54:36 +02:00
connect ( checker , SIGNAL ( succeeded ( QString ) ) , m_instance , SLOT ( slotTopLevelFound ( QString ) ) ) ;
2009-12-11 16:43:39 +01:00
connect ( checker , SIGNAL ( succeeded ( QString ) ) , checker , SLOT ( deleteLater ( ) ) ) ;
2013-08-02 12:54:36 +02:00
checker - > start ( settings ( ) . p4BinaryPath ( ) , settings ( ) . commonP4Arguments ( QString ( ) ) , 30000 ) ;
2009-12-11 16:43:39 +01:00
}
2013-01-28 22:02:35 +02:00
# ifdef WITH_TESTS
void PerforcePlugin : : testLogResolving ( )
{
// Source: http://mail.opensolaris.org/pipermail/opengrok-discuss/2008-October/001668.html
QByteArray data (
" ... #4 change 12345 edit on 2013/01/28 by User at UserWorkspaceName(text) \n "
" \n "
" Comment \n "
" ... #3 change 12344 edit on 2013/01/27 by User at UserWorkspaceName(text) \n "
" \n "
" Comment \n "
) ;
2014-08-21 20:43:33 +02:00
PerforceEditorWidget editor ;
2014-08-21 01:24:38 +02:00
editor . setParameters ( editorParameters ) ;
2013-01-28 22:02:35 +02:00
editor . testLogResolving ( data , " 12345 " , " 12344 " ) ;
}
# endif
2014-08-21 01:24:38 +02:00
} // namespace Internal
} // namespace Perforce
2008-12-02 12:01:29 +01:00
2011-03-31 10:57:33 +02:00
# include "perforceplugin.moc"