2023-01-27 14:17:46 +01:00
// Copyright (c) 2018 Artur Shepilko
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
2016-11-16 12:51:32 -06:00
# include "fossilplugin.h"
2023-02-08 11:15:14 +01:00
# include "commiteditor.h"
# include "configuredialog.h"
2016-11-16 12:51:32 -06:00
# include "constants.h"
# include "fossilclient.h"
# include "fossilcommitwidget.h"
# include "fossileditor.h"
2023-02-08 11:15:14 +01:00
# include "fossiltr.h"
2016-11-16 12:51:32 -06:00
# include "pullorpushdialog.h"
# include "wizard/fossiljsextension.h"
# include <coreplugin/actionmanager/actionmanager.h>
# include <coreplugin/actionmanager/actioncontainer.h>
# include <coreplugin/actionmanager/command.h>
# include <coreplugin/vcsmanager.h>
# include <coreplugin/coreconstants.h>
2017-03-08 17:17:56 +01:00
# include <coreplugin/helpmanager.h>
2016-11-16 12:51:32 -06:00
# include <coreplugin/icore.h>
# include <coreplugin/idocument.h>
# include <coreplugin/documentmanager.h>
# include <coreplugin/editormanager/editormanager.h>
# include <coreplugin/locator/commandlocator.h>
# include <coreplugin/jsexpander.h>
# include <projectexplorer/projectexplorer.h>
# include <projectexplorer/projecttree.h>
# include <projectexplorer/project.h>
# include <projectexplorer/jsonwizard/jsonwizardfactory.h>
2022-03-09 08:18:50 +01:00
# include <utils/commandline.h>
2023-02-07 11:48:03 +01:00
# include <utils/layoutbuilder.h>
2016-11-16 12:51:32 -06:00
# include <utils/parameteraction.h>
# include <utils/qtcassert.h>
# include <vcsbase/basevcseditorfactory.h>
# include <vcsbase/basevcssubmiteditorfactory.h>
2022-07-14 00:05:07 +02:00
# include <vcsbase/vcsbaseclient.h>
2016-11-16 12:51:32 -06:00
# include <vcsbase/vcsbaseconstants.h>
# include <vcsbase/vcsbaseeditor.h>
2022-07-14 00:05:07 +02:00
# include <vcsbase/vcsbasesubmiteditor.h>
2022-08-02 09:08:15 +02:00
# include <vcsbase/vcscommand.h>
2016-11-16 12:51:32 -06:00
# include <vcsbase/vcsoutputwindow.h>
# include <QAction>
# include <QDialog>
2023-02-07 11:48:03 +01:00
# include <QDialogButtonBox>
# include <QDir>
2016-11-16 12:51:32 -06:00
# include <QFileDialog>
2023-02-07 11:48:03 +01:00
# include <QGroupBox>
# include <QMenu>
# include <QMessageBox>
2016-11-16 12:51:32 -06:00
# include <QRegularExpression>
2023-02-07 11:48:03 +01:00
# include <QtPlugin>
2016-11-16 12:51:32 -06:00
2020-02-07 14:23:28 +01:00
using namespace Core ;
using namespace Utils ;
using namespace VcsBase ;
using namespace std : : placeholders ;
2016-11-16 12:51:32 -06:00
namespace Fossil {
namespace Internal {
2020-01-31 14:44:33 +02:00
class FossilTopicCache : public Core : : IVersionControl : : TopicCache
{
public :
FossilTopicCache ( FossilClient * client ) :
m_client ( client )
{ }
protected :
2021-07-29 11:12:22 +02:00
FilePath trackFile ( const FilePath & repository ) final
2020-01-31 14:44:33 +02:00
{
2021-07-29 11:12:22 +02:00
return repository . pathAppended ( Constants : : FOSSILREPO ) ;
2020-01-31 14:44:33 +02:00
}
2021-07-29 11:12:22 +02:00
QString refreshTopic ( const FilePath & repository ) final
2020-01-31 14:44:33 +02:00
{
2021-08-04 09:06:22 +02:00
return m_client - > synchronousTopic ( repository ) ;
2020-01-31 14:44:33 +02:00
}
private :
FossilClient * m_client ;
} ;
2020-02-07 14:23:28 +01:00
const VcsBaseEditorParameters fileLogParameters {
LogOutput ,
Constants : : FILELOG_ID ,
Constants : : FILELOG_DISPLAY_NAME ,
Constants : : LOGAPP
} ;
const VcsBaseEditorParameters annotateLogParameters {
AnnotateOutput ,
Constants : : ANNOTATELOG_ID ,
Constants : : ANNOTATELOG_DISPLAY_NAME ,
Constants : : ANNOTATEAPP
2016-11-16 12:51:32 -06:00
} ;
2020-02-07 14:23:28 +01:00
const VcsBaseEditorParameters diffParameters {
DiffOutput ,
Constants : : DIFFLOG_ID ,
Constants : : DIFFLOG_DISPLAY_NAME ,
Constants : : DIFFAPP
} ;
const VcsBaseSubmitEditorParameters submitEditorParameters {
2016-11-16 12:51:32 -06:00
Constants : : COMMITMIMETYPE ,
Constants : : COMMIT_ID ,
Constants : : COMMIT_DISPLAY_NAME ,
2020-02-07 14:23:28 +01:00
VcsBaseSubmitEditorParameters : : DiffFiles
2016-11-16 12:51:32 -06:00
} ;
2020-02-07 14:23:28 +01:00
class FossilPluginPrivate final : public VcsBase : : VcsBasePluginPrivate
{
public :
2020-06-15 19:22:59 -05:00
enum SyncMode {
SyncPull ,
SyncPush
} ;
2020-02-07 14:23:28 +01:00
FossilPluginPrivate ( ) ;
// IVersionControl
QString displayName ( ) const final ;
2020-07-07 11:47:13 +02:00
Id id ( ) const final ;
2020-02-07 14:23:28 +01:00
2021-07-29 11:12:22 +02:00
bool isVcsFileOrDirectory ( const FilePath & filePath ) const final ;
2020-02-07 14:23:28 +01:00
2021-07-29 11:12:22 +02:00
bool managesDirectory ( const FilePath & directory , FilePath * topLevel ) const final ;
bool managesFile ( const FilePath & workingDirectory , const QString & fileName ) const final ;
2020-02-07 14:23:28 +01:00
bool isConfigured ( ) const final ;
bool supportsOperation ( Operation operation ) const final ;
2021-07-29 11:12:22 +02:00
bool vcsOpen ( const FilePath & fileName ) final ;
bool vcsAdd ( const FilePath & fileName ) final ;
bool vcsDelete ( const FilePath & filename ) final ;
bool vcsMove ( const FilePath & from , const FilePath & to ) final ;
bool vcsCreateRepository ( const FilePath & directory ) final ;
2020-02-07 14:23:28 +01:00
2021-07-29 11:12:22 +02:00
void vcsAnnotate ( const FilePath & file , int line ) final ;
void vcsDescribe ( const FilePath & source , const QString & id ) final ;
2020-02-07 14:23:28 +01:00
2022-08-02 09:08:15 +02:00
VcsCommand * createInitialCheckoutCommand ( const QString & url ,
const Utils : : FilePath & baseDirectory ,
const QString & localName ,
const QStringList & extraArgs ) final ;
2020-02-07 14:23:28 +01:00
void updateActions ( VcsBase : : VcsBasePluginPrivate : : ActionState ) override ;
2022-10-28 14:43:04 +02:00
bool activateCommit ( ) override ;
2020-02-07 14:23:28 +01:00
// File menu action slots
void addCurrentFile ( ) ;
void deleteCurrentFile ( ) ;
void annotateCurrentFile ( ) ;
void diffCurrentFile ( ) ;
void logCurrentFile ( ) ;
void revertCurrentFile ( ) ;
void statusCurrentFile ( ) ;
// Directory menu action slots
void diffRepository ( ) ;
void logRepository ( ) ;
void revertAll ( ) ;
void statusMulti ( ) ;
// Repository menu action slots
2020-06-15 19:22:59 -05:00
void pull ( ) { pullOrPush ( SyncPull ) ; }
void push ( ) { pullOrPush ( SyncPush ) ; }
2020-02-07 14:23:28 +01:00
void update ( ) ;
void configureRepository ( ) ;
void commit ( ) ;
void showCommitWidget ( const QList < VcsBase : : VcsBaseClient : : StatusItem > & status ) ;
void diffFromEditorSelected ( const QStringList & files ) ;
void createRepository ( ) ;
// Methods
void createMenu ( const Core : : Context & context ) ;
void createFileActions ( const Core : : Context & context ) ;
void createDirectoryActions ( const Core : : Context & context ) ;
void createRepositoryActions ( const Core : : Context & context ) ;
2020-06-15 19:22:59 -05:00
bool pullOrPush ( SyncMode mode ) ;
2020-02-07 14:23:28 +01:00
// Variables
2023-05-15 14:52:40 +02:00
FossilSettings m_settings ;
2023-05-15 10:55:16 +02:00
FossilClient m_client ;
2020-02-07 14:23:28 +01:00
VcsSubmitEditorFactory submitEditorFactory {
submitEditorParameters ,
[ ] { return new CommitEditor ; } ,
this
} ;
VcsEditorFactory fileLogFactory {
& fileLogParameters ,
[ ] { return new FossilEditorWidget ; } ,
2020-06-18 00:11:00 +03:00
std : : bind ( & FossilPluginPrivate : : vcsDescribe , this , _1 , _2 )
2020-02-07 14:23:28 +01:00
} ;
VcsEditorFactory annotateLogFactory {
& annotateLogParameters ,
[ ] { return new FossilEditorWidget ; } ,
2020-06-18 00:11:00 +03:00
std : : bind ( & FossilPluginPrivate : : vcsDescribe , this , _1 , _2 )
2020-02-07 14:23:28 +01:00
} ;
VcsEditorFactory diffFactory {
& diffParameters ,
[ ] { return new FossilEditorWidget ; } ,
2020-06-18 00:11:00 +03:00
std : : bind ( & FossilPluginPrivate : : vcsDescribe , this , _1 , _2 )
2020-02-07 14:23:28 +01:00
} ;
Core : : CommandLocator * m_commandLocator = nullptr ;
Core : : ActionContainer * m_fossilContainer = nullptr ;
QList < QAction * > m_repositoryActionList ;
// Menu Items (file actions)
Utils : : ParameterAction * m_addAction = nullptr ;
Utils : : ParameterAction * m_deleteAction = nullptr ;
Utils : : ParameterAction * m_annotateFile = nullptr ;
Utils : : ParameterAction * m_diffFile = nullptr ;
Utils : : ParameterAction * m_logFile = nullptr ;
Utils : : ParameterAction * m_revertFile = nullptr ;
Utils : : ParameterAction * m_statusFile = nullptr ;
QAction * m_createRepositoryAction = nullptr ;
// Submit editor actions
QAction * m_menuAction = nullptr ;
2021-08-04 09:06:22 +02:00
Utils : : FilePath m_submitRepository ;
2020-02-07 14:23:28 +01:00
// To be connected to the VcsTask's success signal to emit the repository/
// files changed signals according to the variant's type:
// String -> repository, StringList -> files
void changed ( const QVariant & ) ;
} ;
2020-01-27 22:46:18 +02:00
static FossilPluginPrivate * dd = nullptr ;
2016-11-16 12:51:32 -06:00
2023-02-07 11:48:03 +01:00
class RevertDialog : public QDialog
{
public :
RevertDialog ( const QString & title , QWidget * parent = nullptr ) ;
QLineEdit * m_revisionLineEdit ;
} ;
2016-11-16 12:51:32 -06:00
FossilPlugin : : ~ FossilPlugin ( )
{
2020-01-27 22:46:18 +02:00
delete dd ;
dd = nullptr ;
2016-11-16 12:51:32 -06:00
}
bool FossilPlugin : : initialize ( const QStringList & arguments , QString * errorMessage )
{
Q_UNUSED ( arguments ) ;
Q_UNUSED ( errorMessage ) ;
2020-01-27 22:46:18 +02:00
dd = new FossilPluginPrivate ;
2023-01-31 10:15:32 +02:00
2020-01-27 22:46:18 +02:00
return true ;
}
void FossilPlugin : : extensionsInitialized ( )
{
dd - > extensionsInitialized ( ) ;
}
2020-02-07 14:23:28 +01:00
FossilClient * FossilPlugin : : client ( )
{
return & dd - > m_client ;
}
2016-11-16 12:51:32 -06:00
2020-02-07 14:23:28 +01:00
FossilPluginPrivate : : FossilPluginPrivate ( )
: VcsBase : : VcsBasePluginPrivate ( Core : : Context ( Constants : : FOSSIL_CONTEXT ) )
{
Core : : Context context ( Constants : : FOSSIL_CONTEXT ) ;
2016-11-16 12:51:32 -06:00
2020-02-07 14:23:28 +01:00
setTopicCache ( new FossilTopicCache ( & m_client ) ) ;
connect ( & m_client , & VcsBase : : VcsBaseClient : : changed , this , & FossilPluginPrivate : : changed ) ;
2016-11-16 12:51:32 -06:00
2018-07-12 15:26:02 -05:00
m_commandLocator = new Core : : CommandLocator ( " Fossil " , " fossil " , " fossil " , this ) ;
2023-03-31 15:49:51 +02:00
m_commandLocator - > setDescription ( Tr : : tr ( " Triggers a Fossil version control operation. " ) ) ;
2016-11-16 12:51:32 -06:00
2019-05-29 10:04:47 +02:00
ProjectExplorer : : JsonWizardFactory : : addWizardPath ( Utils : : FilePath : : fromString ( Constants : : WIZARD_PATH ) ) ;
2023-05-15 10:55:16 +02:00
Core : : JsExpander : : registerGlobalObject ( " Fossil " , [ ] { return new FossilJsExtension ; } ) ;
2016-11-16 12:51:32 -06:00
2023-05-15 10:55:16 +02:00
connect ( & settings ( ) , & AspectContainer : : changed ,
2023-05-15 10:24:35 +02:00
this , & IVersionControl : : configurationChanged ) ;
2016-11-16 12:51:32 -06:00
createMenu ( context ) ;
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : createMenu ( const Core : : Context & context )
2016-11-16 12:51:32 -06:00
{
// Create menu item for Fossil
m_fossilContainer = Core : : ActionManager : : createMenu ( " Fossil.FossilMenu " ) ;
QMenu * menu = m_fossilContainer - > menu ( ) ;
2023-02-07 15:50:44 +01:00
menu - > setTitle ( Tr : : tr ( " &Fossil " ) ) ;
2016-11-16 12:51:32 -06:00
createFileActions ( context ) ;
m_fossilContainer - > addSeparator ( context ) ;
createDirectoryActions ( context ) ;
m_fossilContainer - > addSeparator ( context ) ;
createRepositoryActions ( context ) ;
m_fossilContainer - > addSeparator ( context ) ;
// Request the Tools menu and add the Fossil menu to it
Core : : ActionContainer * toolsMenu = Core : : ActionManager : : actionContainer ( Core : : Constants : : M_TOOLS ) ;
toolsMenu - > addMenu ( m_fossilContainer ) ;
m_menuAction = m_fossilContainer - > menu ( ) - > menuAction ( ) ;
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : createFileActions ( const Core : : Context & context )
2016-11-16 12:51:32 -06:00
{
Core : : Command * command ;
2023-02-07 15:50:44 +01:00
m_annotateFile = new Utils : : ParameterAction ( Tr : : tr ( " Annotate Current File " ) , Tr : : tr ( " Annotate \" %1 \" " ) , Utils : : ParameterAction : : EnabledWithParameter , this ) ;
2016-11-16 12:51:32 -06:00
command = Core : : ActionManager : : registerAction ( m_annotateFile , Constants : : ANNOTATE , context ) ;
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2020-01-27 22:46:18 +02:00
connect ( m_annotateFile , & QAction : : triggered , this , & FossilPluginPrivate : : annotateCurrentFile ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
2023-02-07 15:50:44 +01:00
m_diffFile = new Utils : : ParameterAction ( Tr : : tr ( " Diff Current File " ) , Tr : : tr ( " Diff \" %1 \" " ) , Utils : : ParameterAction : : EnabledWithParameter , this ) ;
2016-11-16 12:51:32 -06:00
command = Core : : ActionManager : : registerAction ( m_diffFile , Constants : : DIFF , context ) ;
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2023-02-07 15:50:44 +01:00
command - > setDefaultKeySequence ( QKeySequence ( Core : : useMacShortcuts ? Tr : : tr ( " Meta+I,Meta+D " )
: Tr : : tr ( " ALT+I,Alt+D " ) ) ) ;
2020-01-27 22:46:18 +02:00
connect ( m_diffFile , & QAction : : triggered , this , & FossilPluginPrivate : : diffCurrentFile ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
2023-02-07 15:50:44 +01:00
m_logFile = new Utils : : ParameterAction ( Tr : : tr ( " Timeline Current File " ) , Tr : : tr ( " Timeline \" %1 \" " ) , Utils : : ParameterAction : : EnabledWithParameter , this ) ;
2016-11-16 12:51:32 -06:00
command = Core : : ActionManager : : registerAction ( m_logFile , Constants : : LOG , context ) ;
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2023-02-07 15:50:44 +01:00
command - > setDefaultKeySequence ( QKeySequence ( Core : : useMacShortcuts ? Tr : : tr ( " Meta+I,Meta+L " )
: Tr : : tr ( " ALT+I,Alt+L " ) ) ) ;
2020-01-27 22:46:18 +02:00
connect ( m_logFile , & QAction : : triggered , this , & FossilPluginPrivate : : logCurrentFile ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
2023-02-07 15:50:44 +01:00
m_statusFile = new Utils : : ParameterAction ( Tr : : tr ( " Status Current File " ) , Tr : : tr ( " Status \" %1 \" " ) , Utils : : ParameterAction : : EnabledWithParameter , this ) ;
2016-11-16 12:51:32 -06:00
command = Core : : ActionManager : : registerAction ( m_statusFile , Constants : : STATUS , context ) ;
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2023-02-07 15:50:44 +01:00
command - > setDefaultKeySequence ( QKeySequence ( Core : : useMacShortcuts ? Tr : : tr ( " Meta+I,Meta+S " )
: Tr : : tr ( " ALT+I,Alt+S " ) ) ) ;
2020-01-27 22:46:18 +02:00
connect ( m_statusFile , & QAction : : triggered , this , & FossilPluginPrivate : : statusCurrentFile ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
m_fossilContainer - > addSeparator ( context ) ;
2023-02-07 15:50:44 +01:00
m_addAction = new Utils : : ParameterAction ( Tr : : tr ( " Add Current File " ) , Tr : : tr ( " Add \" %1 \" " ) , Utils : : ParameterAction : : EnabledWithParameter , this ) ;
2016-11-16 12:51:32 -06:00
command = Core : : ActionManager : : registerAction ( m_addAction , Constants : : ADD , context ) ;
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2020-01-27 22:46:18 +02:00
connect ( m_addAction , & QAction : : triggered , this , & FossilPluginPrivate : : addCurrentFile ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
2023-02-07 15:50:44 +01:00
m_deleteAction = new Utils : : ParameterAction ( Tr : : tr ( " Delete Current File... " ) , Tr : : tr ( " Delete \" %1 \" ... " ) , Utils : : ParameterAction : : EnabledWithParameter , this ) ;
2016-11-16 12:51:32 -06:00
command = Core : : ActionManager : : registerAction ( m_deleteAction , Constants : : DELETE , context ) ;
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2020-01-27 22:46:18 +02:00
connect ( m_deleteAction , & QAction : : triggered , this , & FossilPluginPrivate : : deleteCurrentFile ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
2023-02-07 15:50:44 +01:00
m_revertFile = new Utils : : ParameterAction ( Tr : : tr ( " Revert Current File... " ) , Tr : : tr ( " Revert \" %1 \" ... " ) , Utils : : ParameterAction : : EnabledWithParameter , this ) ;
2016-11-16 12:51:32 -06:00
command = Core : : ActionManager : : registerAction ( m_revertFile , Constants : : REVERT , context ) ;
command - > setAttribute ( Core : : Command : : CA_UpdateText ) ;
2020-01-27 22:46:18 +02:00
connect ( m_revertFile , & QAction : : triggered , this , & FossilPluginPrivate : : revertCurrentFile ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : addCurrentFile ( )
2016-11-16 12:51:32 -06:00
{
const VcsBase : : VcsBasePluginState state = currentState ( ) ;
QTC_ASSERT ( state . hasFile ( ) , return ) ;
2020-02-07 14:23:28 +01:00
m_client . synchronousAdd ( state . currentFileTopLevel ( ) , state . relativeCurrentFile ( ) ) ;
2016-11-16 12:51:32 -06:00
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : deleteCurrentFile ( )
2016-11-16 12:51:32 -06:00
{
promptToDeleteCurrentFile ( ) ;
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : annotateCurrentFile ( )
2016-11-16 12:51:32 -06:00
{
const VcsBase : : VcsBasePluginState state = currentState ( ) ;
QTC_ASSERT ( state . hasFile ( ) , return ) ;
2017-04-20 02:21:51 -05:00
const int lineNumber = VcsBase : : VcsBaseEditor : : lineNumberOfCurrentEditor ( state . currentFile ( ) ) ;
2022-12-11 15:50:21 +01:00
m_client . annotate ( state . currentFileTopLevel ( ) , state . relativeCurrentFile ( ) , lineNumber ) ;
2016-11-16 12:51:32 -06:00
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : diffCurrentFile ( )
2016-11-16 12:51:32 -06:00
{
const VcsBase : : VcsBasePluginState state = currentState ( ) ;
QTC_ASSERT ( state . hasFile ( ) , return ) ;
2020-02-07 14:23:28 +01:00
m_client . diff ( state . currentFileTopLevel ( ) , QStringList ( state . relativeCurrentFile ( ) ) ) ;
2016-11-16 12:51:32 -06:00
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : logCurrentFile ( )
2016-11-16 12:51:32 -06:00
{
const VcsBase : : VcsBasePluginState state = currentState ( ) ;
QTC_ASSERT ( state . hasFile ( ) , return ) ;
2020-02-07 14:23:28 +01:00
FossilClient : : SupportedFeatures features = m_client . supportedFeatures ( ) ;
2016-11-16 12:51:32 -06:00
QStringList extraOptions ;
2023-05-12 16:51:12 +02:00
extraOptions < < " -n " < < QString : : number ( m_client . settings ( ) . logCount ( ) ) ;
2016-11-16 12:51:32 -06:00
if ( features . testFlag ( FossilClient : : TimelineWidthFeature ) )
2023-05-12 16:51:12 +02:00
extraOptions < < " -W " < < QString : : number ( m_client . settings ( ) . timelineWidth ( ) ) ;
2016-11-16 12:51:32 -06:00
2018-07-16 12:25:41 -05:00
// disable annotate context menu for older client versions, used to be supported for current revision only
bool enableAnnotationContextMenu = features . testFlag ( FossilClient : : AnnotateRevisionFeature ) ;
2020-02-07 14:23:28 +01:00
m_client . logCurrentFile ( state . currentFileTopLevel ( ) , QStringList ( state . relativeCurrentFile ( ) ) ,
2016-11-16 12:51:32 -06:00
extraOptions , enableAnnotationContextMenu ) ;
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : revertCurrentFile ( )
2016-11-16 12:51:32 -06:00
{
const VcsBase : : VcsBasePluginState state = currentState ( ) ;
QTC_ASSERT ( state . hasFile ( ) , return ) ;
QDialog dialog ( Core : : ICore : : dialogParent ( ) ) ;
2023-02-07 11:48:03 +01:00
auto revisionLineEdit = new QLineEdit ;
2016-11-16 12:51:32 -06:00
if ( dialog . exec ( ) ! = QDialog : : Accepted )
return ;
2020-02-07 14:23:28 +01:00
m_client . revertFile ( state . currentFileTopLevel ( ) ,
2023-02-07 11:48:03 +01:00
state . relativeCurrentFile ( ) ,
revisionLineEdit - > text ( ) ) ;
2016-11-16 12:51:32 -06:00
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : statusCurrentFile ( )
2016-11-16 12:51:32 -06:00
{
const VcsBase : : VcsBasePluginState state = currentState ( ) ;
QTC_ASSERT ( state . hasFile ( ) , return ) ;
2020-02-07 14:23:28 +01:00
m_client . status ( state . currentFileTopLevel ( ) , state . relativeCurrentFile ( ) ) ;
2016-11-16 12:51:32 -06:00
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : createDirectoryActions ( const Core : : Context & context )
2016-11-16 12:51:32 -06:00
{
QAction * action ;
Core : : Command * command ;
2023-02-07 15:50:44 +01:00
action = new QAction ( Tr : : tr ( " Diff " ) , this ) ;
2016-11-16 12:51:32 -06:00
m_repositoryActionList . append ( action ) ;
command = Core : : ActionManager : : registerAction ( action , Constants : : DIFFMULTI , context ) ;
2020-01-27 22:46:18 +02:00
connect ( action , & QAction : : triggered , this , & FossilPluginPrivate : : diffRepository ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
2023-02-07 15:50:44 +01:00
action = new QAction ( Tr : : tr ( " Timeline " ) , this ) ;
2016-11-16 12:51:32 -06:00
m_repositoryActionList . append ( action ) ;
command = Core : : ActionManager : : registerAction ( action , Constants : : LOGMULTI , context ) ;
2023-02-07 15:50:44 +01:00
command - > setDefaultKeySequence ( QKeySequence ( Core : : useMacShortcuts ? Tr : : tr ( " Meta+I,Meta+T " )
: Tr : : tr ( " ALT+I,Alt+T " ) ) ) ;
2020-01-27 22:46:18 +02:00
connect ( action , & QAction : : triggered , this , & FossilPluginPrivate : : logRepository ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
2023-02-07 15:50:44 +01:00
action = new QAction ( Tr : : tr ( " Revert... " ) , this ) ;
2016-11-16 12:51:32 -06:00
m_repositoryActionList . append ( action ) ;
command = Core : : ActionManager : : registerAction ( action , Constants : : REVERTMULTI , context ) ;
2020-01-27 22:46:18 +02:00
connect ( action , & QAction : : triggered , this , & FossilPluginPrivate : : revertAll ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
2023-02-07 15:50:44 +01:00
action = new QAction ( Tr : : tr ( " Status " ) , this ) ;
2016-11-16 12:51:32 -06:00
m_repositoryActionList . append ( action ) ;
command = Core : : ActionManager : : registerAction ( action , Constants : : STATUSMULTI , context ) ;
2020-01-27 22:46:18 +02:00
connect ( action , & QAction : : triggered , this , & FossilPluginPrivate : : statusMulti ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : diffRepository ( )
2016-11-16 12:51:32 -06:00
{
const VcsBase : : VcsBasePluginState state = currentState ( ) ;
QTC_ASSERT ( state . hasTopLevel ( ) , return ) ;
2020-02-07 14:23:28 +01:00
m_client . diff ( state . topLevel ( ) ) ;
2016-11-16 12:51:32 -06:00
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : logRepository ( )
2016-11-16 12:51:32 -06:00
{
const VcsBase : : VcsBasePluginState state = currentState ( ) ;
QTC_ASSERT ( state . hasTopLevel ( ) , return ) ;
2020-02-07 14:23:28 +01:00
FossilClient : : SupportedFeatures features = m_client . supportedFeatures ( ) ;
2016-11-16 12:51:32 -06:00
QStringList extraOptions ;
2023-05-12 16:51:12 +02:00
extraOptions < < " -n " < < QString : : number ( m_client . settings ( ) . logCount ( ) ) ;
2016-11-16 12:51:32 -06:00
if ( features . testFlag ( FossilClient : : TimelineWidthFeature ) )
2023-05-12 16:51:12 +02:00
extraOptions < < " -W " < < QString : : number ( m_client . settings ( ) . timelineWidth ( ) ) ;
2016-11-16 12:51:32 -06:00
2022-10-06 19:34:47 +02:00
m_client . log ( state . topLevel ( ) , { } , extraOptions ) ;
2016-11-16 12:51:32 -06:00
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : revertAll ( )
2016-11-16 12:51:32 -06:00
{
const VcsBase : : VcsBasePluginState state = currentState ( ) ;
QTC_ASSERT ( state . hasTopLevel ( ) , return ) ;
2023-02-07 15:50:44 +01:00
RevertDialog dialog ( Tr : : tr ( " Revert " ) , Core : : ICore : : dialogParent ( ) ) ;
2023-02-07 11:48:03 +01:00
if ( dialog . exec ( ) = = QDialog : : Accepted )
m_client . revertAll ( state . topLevel ( ) , dialog . m_revisionLineEdit - > text ( ) ) ;
2016-11-16 12:51:32 -06:00
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : statusMulti ( )
2016-11-16 12:51:32 -06:00
{
const VcsBase : : VcsBasePluginState state = currentState ( ) ;
QTC_ASSERT ( state . hasTopLevel ( ) , return ) ;
2020-02-07 14:23:28 +01:00
m_client . status ( state . topLevel ( ) ) ;
2016-11-16 12:51:32 -06:00
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : createRepositoryActions ( const Core : : Context & context )
2016-11-16 12:51:32 -06:00
{
QAction * action = 0 ;
Core : : Command * command = 0 ;
2023-02-07 15:50:44 +01:00
action = new QAction ( Tr : : tr ( " Pull... " ) , this ) ;
2016-11-16 12:51:32 -06:00
m_repositoryActionList . append ( action ) ;
command = Core : : ActionManager : : registerAction ( action , Constants : : PULL , context ) ;
2020-01-27 22:46:18 +02:00
connect ( action , & QAction : : triggered , this , & FossilPluginPrivate : : pull ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
2023-02-07 15:50:44 +01:00
action = new QAction ( Tr : : tr ( " Push... " ) , this ) ;
2016-11-16 12:51:32 -06:00
m_repositoryActionList . append ( action ) ;
command = Core : : ActionManager : : registerAction ( action , Constants : : PUSH , context ) ;
2020-01-27 22:46:18 +02:00
connect ( action , & QAction : : triggered , this , & FossilPluginPrivate : : push ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
2023-02-07 15:50:44 +01:00
action = new QAction ( Tr : : tr ( " Update... " ) , this ) ;
2016-11-16 12:51:32 -06:00
m_repositoryActionList . append ( action ) ;
command = Core : : ActionManager : : registerAction ( action , Constants : : UPDATE , context ) ;
2023-02-07 15:50:44 +01:00
command - > setDefaultKeySequence ( QKeySequence ( Core : : useMacShortcuts ? Tr : : tr ( " Meta+I,Meta+U " )
: Tr : : tr ( " ALT+I,Alt+U " ) ) ) ;
2020-01-27 22:46:18 +02:00
connect ( action , & QAction : : triggered , this , & FossilPluginPrivate : : update ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
2023-02-07 15:50:44 +01:00
action = new QAction ( Tr : : tr ( " Commit... " ) , this ) ;
2016-11-16 12:51:32 -06:00
m_repositoryActionList . append ( action ) ;
command = Core : : ActionManager : : registerAction ( action , Constants : : COMMIT , context ) ;
2023-02-07 15:50:44 +01:00
command - > setDefaultKeySequence ( QKeySequence ( Core : : useMacShortcuts ? Tr : : tr ( " Meta+I,Meta+C " )
: Tr : : tr ( " ALT+I,Alt+C " ) ) ) ;
2020-01-27 22:46:18 +02:00
connect ( action , & QAction : : triggered , this , & FossilPluginPrivate : : commit ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
2023-02-07 15:50:44 +01:00
action = new QAction ( Tr : : tr ( " Settings ... " ) , this ) ;
2016-11-16 12:51:32 -06:00
m_repositoryActionList . append ( action ) ;
command = Core : : ActionManager : : registerAction ( action , Constants : : CONFIGURE_REPOSITORY , context ) ;
2020-01-27 22:46:18 +02:00
connect ( action , & QAction : : triggered , this , & FossilPluginPrivate : : configureRepository ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
m_commandLocator - > appendCommand ( command ) ;
// Register "Create Repository..." action in global context, so that it's visible
// without active repository to allow creating a new one.
2023-02-07 15:50:44 +01:00
m_createRepositoryAction = new QAction ( Tr : : tr ( " Create Repository... " ) , this ) ;
2016-11-16 12:51:32 -06:00
command = Core : : ActionManager : : registerAction ( m_createRepositoryAction , Constants : : CREATE_REPOSITORY ) ;
2020-01-27 22:46:18 +02:00
connect ( m_createRepositoryAction , & QAction : : triggered , this , & FossilPluginPrivate : : createRepository ) ;
2016-11-16 12:51:32 -06:00
m_fossilContainer - > addAction ( command ) ;
}
2020-06-15 19:22:59 -05:00
bool FossilPluginPrivate : : pullOrPush ( FossilPluginPrivate : : SyncMode mode )
2016-11-16 12:51:32 -06:00
{
2020-06-15 19:22:59 -05:00
PullOrPushDialog : : Mode pullOrPushMode ;
switch ( mode ) {
case SyncPull :
pullOrPushMode = PullOrPushDialog : : PullMode ;
break ;
case SyncPush :
pullOrPushMode = PullOrPushDialog : : PushMode ;
break ;
default :
return false ;
2016-11-16 12:51:32 -06:00
}
const VcsBase : : VcsBasePluginState state = currentState ( ) ;
2020-06-15 19:22:59 -05:00
QTC_ASSERT ( state . hasTopLevel ( ) , return false ) ;
2016-11-16 12:51:32 -06:00
2020-06-15 19:22:59 -05:00
PullOrPushDialog dialog ( pullOrPushMode , Core : : ICore : : dialogParent ( ) ) ;
2021-03-19 16:07:25 +01:00
dialog . setLocalBaseDirectory ( m_client . settings ( ) . defaultRepoPath . value ( ) ) ;
2020-06-15 19:22:59 -05:00
const QString defaultURL ( m_client . synchronousGetRepositoryURL ( state . topLevel ( ) ) ) ;
dialog . setDefaultRemoteLocation ( defaultURL ) ;
2016-11-16 12:51:32 -06:00
if ( dialog . exec ( ) ! = QDialog : : Accepted )
2020-06-15 19:22:59 -05:00
return true ;
2016-11-16 12:51:32 -06:00
QString remoteLocation ( dialog . remoteLocation ( ) ) ;
2020-06-15 19:22:59 -05:00
if ( remoteLocation . isEmpty ( ) & & defaultURL . isEmpty ( ) ) {
2023-02-07 15:50:44 +01:00
VcsBase : : VcsOutputWindow : : appendError ( Tr : : tr ( " Remote repository is not defined. " ) ) ;
2020-06-15 19:22:59 -05:00
return false ;
} else if ( remoteLocation = = defaultURL ) {
remoteLocation . clear ( ) ;
2016-11-16 12:51:32 -06:00
}
QStringList extraOptions ;
2020-06-15 19:22:59 -05:00
if ( ! remoteLocation . isEmpty ( ) & & ! dialog . isRememberOptionEnabled ( ) )
2016-11-16 12:51:32 -06:00
extraOptions < < " --once " ;
if ( dialog . isPrivateOptionEnabled ( ) )
extraOptions < < " --private " ;
2020-06-15 19:22:59 -05:00
switch ( mode ) {
case SyncPull :
return m_client . synchronousPull ( state . topLevel ( ) , remoteLocation , extraOptions ) ;
case SyncPush :
return m_client . synchronousPush ( state . topLevel ( ) , remoteLocation , extraOptions ) ;
default :
return false ;
}
2016-11-16 12:51:32 -06:00
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : update ( )
2016-11-16 12:51:32 -06:00
{
const VcsBase : : VcsBasePluginState state = currentState ( ) ;
QTC_ASSERT ( state . hasTopLevel ( ) , return ) ;
2023-02-07 15:50:44 +01:00
RevertDialog dialog ( Tr : : tr ( " Update " ) , Core : : ICore : : dialogParent ( ) ) ;
2023-02-07 11:48:03 +01:00
if ( dialog . exec ( ) = = QDialog : : Accepted )
m_client . update ( state . topLevel ( ) , dialog . m_revisionLineEdit - > text ( ) ) ;
2016-11-16 12:51:32 -06:00
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : configureRepository ( )
2016-11-16 12:51:32 -06:00
{
const VcsBase : : VcsBasePluginState state = currentState ( ) ;
QTC_ASSERT ( state . hasTopLevel ( ) , return ) ;
ConfigureDialog dialog ;
// retrieve current settings from the repository
2020-02-07 14:23:28 +01:00
RepositorySettings currentSettings = m_client . synchronousSettingsQuery ( state . topLevel ( ) ) ;
2016-11-16 12:51:32 -06:00
dialog . setSettings ( currentSettings ) ;
if ( dialog . exec ( ) ! = QDialog : : Accepted )
return ;
const RepositorySettings newSettings = dialog . settings ( ) ;
2020-02-07 14:23:28 +01:00
m_client . synchronousConfigureRepository ( state . topLevel ( ) , newSettings , currentSettings ) ;
2016-11-16 12:51:32 -06:00
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : commit ( )
2016-11-16 12:51:32 -06:00
{
2018-07-12 15:26:02 -05:00
if ( ! promptBeforeCommit ( ) )
return ;
2016-11-16 12:51:32 -06:00
if ( raiseSubmitEditor ( ) )
return ;
const VcsBase : : VcsBasePluginState state = currentState ( ) ;
QTC_ASSERT ( state . hasTopLevel ( ) , return ) ;
m_submitRepository = state . topLevel ( ) ;
2022-10-07 08:38:02 +02:00
connect ( & m_client , & VcsBaseClient : : parsedStatus , this , & FossilPluginPrivate : : showCommitWidget ) ;
m_client . emitParsedStatus ( m_submitRepository , { } ) ;
2016-11-16 12:51:32 -06:00
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : showCommitWidget ( const QList < VcsBase : : VcsBaseClient : : StatusItem > & status )
2016-11-16 12:51:32 -06:00
{
//Once we receive our data release the connection so it can be reused elsewhere
2020-02-07 14:23:28 +01:00
disconnect ( & m_client , & VcsBaseClient : : parsedStatus ,
2020-01-27 22:46:18 +02:00
this , & FossilPluginPrivate : : showCommitWidget ) ;
2016-11-16 12:51:32 -06:00
if ( status . isEmpty ( ) ) {
2023-02-07 15:50:44 +01:00
VcsBase : : VcsOutputWindow : : appendError ( Tr : : tr ( " There are no changes to commit. " ) ) ;
2016-11-16 12:51:32 -06:00
return ;
}
// Start new temp file for commit message
Utils : : TempFileSaver saver ;
// Keep the file alive, else it removes self and forgets its name
saver . setAutoRemove ( false ) ;
if ( ! saver . finalize ( ) ) {
VcsBase : : VcsOutputWindow : : appendError ( saver . errorString ( ) ) ;
return ;
}
2021-11-03 08:17:57 +01:00
Core : : IEditor * editor = Core : : EditorManager : : openEditor ( saver . filePath ( ) , Constants : : COMMIT_ID ) ;
2016-11-16 12:51:32 -06:00
if ( ! editor ) {
2023-02-07 15:50:44 +01:00
VcsBase : : VcsOutputWindow : : appendError ( Tr : : tr ( " Unable to create an editor for the commit. " ) ) ;
2016-11-16 12:51:32 -06:00
return ;
}
CommitEditor * commitEditor = qobject_cast < CommitEditor * > ( editor ) ;
if ( ! commitEditor ) {
2023-02-07 15:50:44 +01:00
VcsBase : : VcsOutputWindow : : appendError ( Tr : : tr ( " Unable to create a commit editor. " ) ) ;
2016-11-16 12:51:32 -06:00
return ;
}
setSubmitEditor ( commitEditor ) ;
2023-02-07 15:50:44 +01:00
const QString msg = Tr : : tr ( " Commit changes for \" %1 \" . " ) . arg ( m_submitRepository . toUserOutput ( ) ) ;
2016-11-16 12:51:32 -06:00
commitEditor - > document ( ) - > setPreferredDisplayName ( msg ) ;
2020-02-07 14:23:28 +01:00
const RevisionInfo currentRevision = m_client . synchronousRevisionQuery ( m_submitRepository ) ;
const BranchInfo currentBranch = m_client . synchronousCurrentBranch ( m_submitRepository ) ;
const QString currentUser = m_client . synchronousUserDefaultQuery ( m_submitRepository ) ;
QStringList tags = m_client . synchronousTagQuery ( m_submitRepository , currentRevision . id ) ;
2016-11-16 12:51:32 -06:00
// Fossil includes branch name in tag list -- remove.
2022-10-06 19:34:47 +02:00
tags . removeAll ( currentBranch . name ) ;
2022-11-11 08:15:45 +01:00
commitEditor - > setFields ( m_submitRepository , currentBranch , tags , currentUser , status ) ;
2016-11-16 12:51:32 -06:00
connect ( commitEditor , & VcsBase : : VcsBaseSubmitEditor : : diffSelectedFiles ,
2020-01-27 22:46:18 +02:00
this , & FossilPluginPrivate : : diffFromEditorSelected ) ;
2016-11-16 12:51:32 -06:00
commitEditor - > setCheckScriptWorkingDirectory ( m_submitRepository ) ;
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : diffFromEditorSelected ( const QStringList & files )
2016-11-16 12:51:32 -06:00
{
2020-02-07 14:23:28 +01:00
m_client . diff ( m_submitRepository , files ) ;
2016-11-16 12:51:32 -06:00
}
static inline bool ask ( QWidget * parent , const QString & title , const QString & question , bool defaultValue = true )
{
const QMessageBox : : StandardButton defaultButton = defaultValue ? QMessageBox : : Yes : QMessageBox : : No ;
return QMessageBox : : question ( parent , title , question , QMessageBox : : Yes | QMessageBox : : No , defaultButton ) = = QMessageBox : : Yes ;
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : createRepository ( )
2016-11-16 12:51:32 -06:00
{
// re-implemented from void VcsBasePlugin::createRepository()
// Find current starting directory
2021-08-04 09:06:22 +02:00
Utils : : FilePath directory ;
2016-11-16 12:51:32 -06:00
if ( const ProjectExplorer : : Project * currentProject = ProjectExplorer : : ProjectTree : : currentProject ( ) )
2021-08-04 09:06:22 +02:00
directory = currentProject - > projectDirectory ( ) ;
2016-11-16 12:51:32 -06:00
// Prompt for a directory that is not under version control yet
2022-07-27 10:58:45 +02:00
QWidget * mw = Core : : ICore : : dialogParent ( ) ;
2016-11-16 12:51:32 -06:00
do {
2023-02-07 15:50:44 +01:00
directory = FileUtils : : getExistingDirectory ( nullptr , Tr : : tr ( " Choose Checkout Directory " ) , directory ) ;
2016-11-16 12:51:32 -06:00
if ( directory . isEmpty ( ) )
return ;
const Core : : IVersionControl * managingControl = Core : : VcsManager : : findVersionControlForDirectory ( directory ) ;
if ( managingControl = = 0 )
break ;
2023-02-07 15:50:44 +01:00
const QString question = Tr : : tr ( " The directory \" %1 \" is already managed by a version control system (%2). "
2021-08-04 09:06:22 +02:00
" Would you like to specify another directory? " ) . arg ( directory . toUserOutput ( ) , managingControl - > displayName ( ) ) ;
2016-11-16 12:51:32 -06:00
2023-02-07 15:50:44 +01:00
if ( ! ask ( mw , Tr : : tr ( " Repository already under version control " ) , question ) )
2016-11-16 12:51:32 -06:00
return ;
} while ( true ) ;
// Create
2021-08-04 09:06:22 +02:00
const bool rc = vcsCreateRepository ( directory ) ;
const QString nativeDir = directory . toUserOutput ( ) ;
2016-11-16 12:51:32 -06:00
if ( rc ) {
2023-02-07 15:50:44 +01:00
QMessageBox : : information ( mw , Tr : : tr ( " Repository Created " ) ,
Tr : : tr ( " A version control repository has been created in %1. " ) .
2016-11-16 12:51:32 -06:00
arg ( nativeDir ) ) ;
} else {
2023-02-07 15:50:44 +01:00
QMessageBox : : warning ( mw , Tr : : tr ( " Repository Creation Failed " ) ,
Tr : : tr ( " A version control repository could not be created in %1. " ) .
2016-11-16 12:51:32 -06:00
arg ( nativeDir ) ) ;
}
}
2022-10-28 14:43:04 +02:00
bool FossilPluginPrivate : : activateCommit ( )
2016-11-16 12:51:32 -06:00
{
CommitEditor * commitEditor = qobject_cast < CommitEditor * > ( submitEditor ( ) ) ;
QTC_ASSERT ( commitEditor , return true ) ;
Core : : IDocument * editorDocument = commitEditor - > document ( ) ;
QTC_ASSERT ( editorDocument , return true ) ;
QStringList files = commitEditor - > checkedFiles ( ) ;
if ( ! files . empty ( ) ) {
//save the commit message
if ( ! Core : : DocumentManager : : saveDocument ( editorDocument ) )
return false ;
//rewrite entries of the form 'file => newfile' to 'newfile' because
//this would mess the commit command
for ( QStringList : : iterator iFile = files . begin ( ) ; iFile ! = files . end ( ) ; + + iFile ) {
2021-03-19 16:07:25 +01:00
const QStringList parts = iFile - > split ( " => " , Qt : : SkipEmptyParts ) ;
2016-11-16 12:51:32 -06:00
if ( ! parts . isEmpty ( ) )
* iFile = parts . last ( ) ;
}
FossilCommitWidget * commitWidget = commitEditor - > commitWidget ( ) ;
QStringList extraOptions ;
// Author -- override the repository-default user
if ( ! commitWidget - > committer ( ) . isEmpty ( ) )
extraOptions < < " --user " < < commitWidget - > committer ( ) ;
// Branch
QString branch = commitWidget - > newBranch ( ) ;
if ( ! branch . isEmpty ( ) ) {
// @TODO: make enquote utility function
QString enquotedBranch = branch ;
if ( branch . contains ( QRegularExpression ( " \\ s " ) ) )
enquotedBranch = QString ( " \" " ) + branch + " \" " ;
extraOptions < < " --branch " < < enquotedBranch ;
}
// Tags
2022-10-06 20:00:31 +02:00
const QStringList tags = commitWidget - > tags ( ) ;
for ( const QString & tag : tags ) {
2016-11-16 12:51:32 -06:00
extraOptions < < " --tag " < < tag ;
}
// Whether local commit or not
if ( commitWidget - > isPrivateOptionEnabled ( ) )
extraOptions + = " --private " ;
2020-02-07 14:23:28 +01:00
m_client . commit ( m_submitRepository , files , editorDocument - > filePath ( ) . toString ( ) , extraOptions ) ;
2016-11-16 12:51:32 -06:00
}
return true ;
}
2020-01-27 22:46:18 +02:00
void FossilPluginPrivate : : updateActions ( VcsBase : : VcsBasePluginPrivate : : ActionState as )
2016-11-16 12:51:32 -06:00
{
m_createRepositoryAction - > setEnabled ( true ) ;
if ( ! enableMenuAction ( as , m_menuAction ) ) {
m_commandLocator - > setEnabled ( false ) ;
return ;
}
const QString filename = currentState ( ) . currentFileName ( ) ;
const bool repoEnabled = currentState ( ) . hasTopLevel ( ) ;
m_commandLocator - > setEnabled ( repoEnabled ) ;
m_annotateFile - > setParameter ( filename ) ;
m_diffFile - > setParameter ( filename ) ;
m_logFile - > setParameter ( filename ) ;
m_addAction - > setParameter ( filename ) ;
m_deleteAction - > setParameter ( filename ) ;
m_revertFile - > setParameter ( filename ) ;
m_statusFile - > setParameter ( filename ) ;
2022-10-06 20:00:31 +02:00
for ( QAction * repoAction : qAsConst ( m_repositoryActionList ) )
2016-11-16 12:51:32 -06:00
repoAction - > setEnabled ( repoEnabled ) ;
}
2020-01-31 14:44:33 +02:00
QString FossilPluginPrivate : : displayName ( ) const
{
2023-02-07 15:50:44 +01:00
return Tr : : tr ( " Fossil " ) ;
2020-01-31 14:44:33 +02:00
}
2020-07-07 11:47:13 +02:00
Id FossilPluginPrivate : : id ( ) const
2020-01-31 14:44:33 +02:00
{
2020-07-07 11:47:13 +02:00
return Id ( Constants : : VCS_ID_FOSSIL ) ;
2020-01-31 14:44:33 +02:00
}
2021-07-29 11:12:22 +02:00
bool FossilPluginPrivate : : isVcsFileOrDirectory ( const FilePath & filePath ) const
2020-01-31 14:44:33 +02:00
{
2020-02-07 14:23:28 +01:00
return m_client . isVcsFileOrDirectory ( filePath ) ;
2020-01-31 14:44:33 +02:00
}
2021-07-29 11:12:22 +02:00
bool FossilPluginPrivate : : managesDirectory ( const FilePath & directory , FilePath * topLevel ) const
2020-01-31 14:44:33 +02:00
{
2021-07-30 09:13:55 +02:00
const FilePath topLevelFound = m_client . findTopLevelForFile ( directory ) ;
2020-01-31 14:44:33 +02:00
if ( topLevel )
2021-07-30 09:13:55 +02:00
* topLevel = topLevelFound ;
2020-01-31 14:44:33 +02:00
return ! topLevelFound . isEmpty ( ) ;
}
2021-07-29 11:12:22 +02:00
bool FossilPluginPrivate : : managesFile ( const FilePath & workingDirectory , const QString & fileName ) const
2020-01-31 14:44:33 +02:00
{
2021-08-04 09:06:22 +02:00
return m_client . managesFile ( workingDirectory , fileName ) ;
2020-01-31 14:44:33 +02:00
}
bool FossilPluginPrivate : : isConfigured ( ) const
{
2020-02-07 14:23:28 +01:00
const Utils : : FilePath binary = m_client . vcsBinary ( ) ;
2020-01-31 14:44:33 +02:00
if ( binary . isEmpty ( ) )
return false ;
const QFileInfo fi = binary . toFileInfo ( ) ;
if ( ! ( fi . exists ( ) & & fi . isFile ( ) & & fi . isExecutable ( ) ) )
return false ;
// Local repositories default path must be set and exist
2021-03-19 16:07:25 +01:00
const QString repoPath = m_client . settings ( ) . defaultRepoPath . value ( ) ;
2020-01-31 14:44:33 +02:00
if ( repoPath . isEmpty ( ) )
return false ;
const QDir dir ( repoPath ) ;
if ( ! dir . exists ( ) )
return false ;
return true ;
}
bool FossilPluginPrivate : : supportsOperation ( Operation operation ) const
{
bool supported = isConfigured ( ) ;
switch ( operation ) {
case Core : : IVersionControl : : AddOperation :
case Core : : IVersionControl : : DeleteOperation :
case Core : : IVersionControl : : MoveOperation :
case Core : : IVersionControl : : CreateRepositoryOperation :
case Core : : IVersionControl : : AnnotateOperation :
case Core : : IVersionControl : : InitialCheckoutOperation :
break ;
case Core : : IVersionControl : : SnapshotOperations :
supported = false ;
break ;
}
return supported ;
}
2021-07-29 11:12:22 +02:00
bool FossilPluginPrivate : : vcsOpen ( const FilePath & filePath )
2020-01-31 14:44:33 +02:00
{
2021-07-29 11:12:22 +02:00
Q_UNUSED ( filePath )
2020-01-31 14:44:33 +02:00
return true ;
}
2021-07-29 11:12:22 +02:00
bool FossilPluginPrivate : : vcsAdd ( const FilePath & filePath )
2020-01-31 14:44:33 +02:00
{
2021-08-04 09:06:22 +02:00
return m_client . synchronousAdd ( filePath . absolutePath ( ) , filePath . fileName ( ) ) ;
2020-01-31 14:44:33 +02:00
}
2021-07-29 11:12:22 +02:00
bool FossilPluginPrivate : : vcsDelete ( const FilePath & filePath )
2020-01-31 14:44:33 +02:00
{
2021-08-04 09:06:22 +02:00
return m_client . synchronousRemove ( filePath . absolutePath ( ) , filePath . fileName ( ) ) ;
2020-01-31 14:44:33 +02:00
}
2021-07-29 11:12:22 +02:00
bool FossilPluginPrivate : : vcsMove ( const FilePath & from , const FilePath & to )
2020-01-31 14:44:33 +02:00
{
2021-07-29 11:12:22 +02:00
const QFileInfo fromInfo = from . toFileInfo ( ) ;
const QFileInfo toInfo = to . toFileInfo ( ) ;
2022-10-06 19:34:47 +02:00
return m_client . synchronousMove ( from . absolutePath ( ) , fromInfo . absoluteFilePath ( ) ,
2021-08-04 09:06:22 +02:00
toInfo . absoluteFilePath ( ) ) ;
2020-01-31 14:44:33 +02:00
}
2021-07-29 11:12:22 +02:00
bool FossilPluginPrivate : : vcsCreateRepository ( const FilePath & directory )
2020-01-31 14:44:33 +02:00
{
2021-08-04 09:06:22 +02:00
return m_client . synchronousCreateRepository ( directory ) ;
2020-01-31 14:44:33 +02:00
}
2021-07-29 11:12:22 +02:00
void FossilPluginPrivate : : vcsAnnotate ( const FilePath & filePath , int line )
2020-01-31 14:44:33 +02:00
{
2022-12-11 15:50:21 +01:00
m_client . annotate ( filePath . absolutePath ( ) , filePath . fileName ( ) , line ) ;
2020-01-31 14:44:33 +02:00
}
2022-10-06 19:34:47 +02:00
void FossilPluginPrivate : : vcsDescribe ( const FilePath & source , const QString & id )
{
2023-01-20 13:07:51 +01:00
m_client . view ( source , id ) ;
2022-10-06 19:34:47 +02:00
}
2021-07-29 11:12:22 +02:00
2022-08-02 09:08:15 +02:00
VcsCommand * FossilPluginPrivate : : createInitialCheckoutCommand ( const QString & sourceUrl ,
const FilePath & baseDirectory ,
const QString & localName ,
const QStringList & extraArgs )
2020-01-31 14:44:33 +02:00
{
2022-10-06 20:04:04 +02:00
const QMap < QString , QString > options = FossilJsExtension : : parseArgOptions ( extraArgs ) ;
2020-01-31 14:44:33 +02:00
// Two operating modes:
// 1) CloneCheckout:
// -- clone from remote-URL or a local-fossil a repository into a local-clone fossil.
// -- open/checkout the local-clone fossil
// The local-clone fossil must not point to an existing repository.
// Clone URL may be either schema-based (http, ssh, file) or an absolute local path.
//
// 2) LocalCheckout:
// -- open/checkout an existing local fossil
// Clone URL is an absolute local path and is the same as the local fossil.
2021-08-04 09:06:22 +02:00
const Utils : : FilePath checkoutPath = baseDirectory . pathAppended ( localName ) ;
2020-01-31 14:44:33 +02:00
const QString fossilFile = options . value ( " fossil-file " ) ;
const Utils : : FilePath fossilFilePath = Utils : : FilePath : : fromUserInput ( QDir : : fromNativeSeparators ( fossilFile ) ) ;
const QString fossilFileNative = fossilFilePath . toUserOutput ( ) ;
const QFileInfo cloneRepository ( fossilFilePath . toString ( ) ) ;
// Check when requested to clone a local repository and clone-into repository file is the same
// or not specified.
// In this case handle it as local fossil checkout request.
const QUrl url ( sourceUrl ) ;
bool isLocalRepository = ( options . value ( " repository-type " ) = = " localRepo " ) ;
if ( url . isLocalFile ( ) | | url . isRelative ( ) ) {
const QFileInfo sourcePath ( url . path ( ) ) ;
isLocalRepository = ( sourcePath . canonicalFilePath ( ) = = cloneRepository . canonicalFilePath ( ) ) ;
}
// set clone repository admin user to configured user name
// OR override it with the specified user from clone panel
const QString adminUser = options . value ( " admin-user " ) ;
const bool disableAutosync = ( options . value ( " settings-autosync " ) = = " off " ) ;
const QString checkoutBranch = options . value ( " branch-tag " ) ;
// first create the checkout directory,
// as it needs to become a working directory for wizard command jobs
2021-08-04 09:06:22 +02:00
checkoutPath . createDir ( ) ;
2020-01-31 14:44:33 +02:00
// Setup the wizard page command job
2022-07-14 00:05:07 +02:00
auto command = VcsBaseClient : : createVcsCommand ( checkoutPath , m_client . processEnvironment ( ) ) ;
2020-01-31 14:44:33 +02:00
if ( ! isLocalRepository
& & ! cloneRepository . exists ( ) ) {
const QString sslIdentityFile = options . value ( " ssl-identity " ) ;
const Utils : : FilePath sslIdentityFilePath = Utils : : FilePath : : fromUserInput ( QDir : : fromNativeSeparators ( sslIdentityFile ) ) ;
const bool includePrivate = ( options . value ( " include-private " ) = = " true " ) ;
QStringList extraOptions ;
if ( includePrivate )
extraOptions < < " --private " ;
if ( ! sslIdentityFile . isEmpty ( ) )
extraOptions < < " --ssl-identity " < < sslIdentityFilePath . toUserOutput ( ) ;
if ( ! adminUser . isEmpty ( ) )
extraOptions < < " --admin-user " < < adminUser ;
// Fossil allows saving the remote address and login. This is used to
// facilitate autosync (commit/update) functionality.
// When no password is given, it prompts for that.
// When both username and password are specified, it prompts whether to
// save them.
// NOTE: In non-interactive context, these prompts won't work.
// Fossil currently does not support SSH_ASKPASS way for login query.
//
// Alternatively, "--once" option does not save the remote details.
// In such case remote details must be provided on the command-line every
// time. This also precludes autosync.
//
// So here we want Fossil to save the remote details when specified.
QStringList args ;
2020-02-07 14:23:28 +01:00
args < < m_client . vcsCommandString ( FossilClient : : CloneCommand )
2020-01-31 14:44:33 +02:00
< < extraOptions
< < sourceUrl
< < fossilFileNative ;
2020-02-07 14:23:28 +01:00
command - > addJob ( { m_client . vcsBinary ( ) , args } , - 1 ) ;
2020-01-31 14:44:33 +02:00
}
// check out the cloned repository file into the working copy directory;
// by default the latest revision is checked out
QStringList args ( { " open " , fossilFileNative } ) ;
if ( ! checkoutBranch . isEmpty ( ) )
args < < checkoutBranch ;
2020-02-07 14:23:28 +01:00
command - > addJob ( { m_client . vcsBinary ( ) , args } , - 1 ) ;
2020-01-31 14:44:33 +02:00
// set user default to admin user if specified
if ( ! isLocalRepository
& & ! adminUser . isEmpty ( ) ) {
const QStringList args ( { " user " , " default " , adminUser , " --user " , adminUser } ) ;
2020-02-07 14:23:28 +01:00
command - > addJob ( { m_client . vcsBinary ( ) , args } , - 1 ) ;
2020-01-31 14:44:33 +02:00
}
// turn-off autosync if requested
if ( ! isLocalRepository
& & disableAutosync ) {
const QStringList args ( { " settings " , " autosync " , " off " } ) ;
2020-02-07 14:23:28 +01:00
command - > addJob ( { m_client . vcsBinary ( ) , args } , - 1 ) ;
2020-01-31 14:44:33 +02:00
}
return command ;
}
void FossilPluginPrivate : : changed ( const QVariant & v )
{
switch ( v . type ( ) ) {
case QVariant : : String :
2021-08-04 09:06:22 +02:00
emit repositoryChanged ( Utils : : FilePath : : fromVariant ( v ) ) ;
2020-01-31 14:44:33 +02:00
break ;
case QVariant : : StringList :
emit filesChanged ( v . toStringList ( ) ) ;
break ;
default :
break ;
}
}
2023-02-07 11:48:03 +01:00
RevertDialog : : RevertDialog ( const QString & title , QWidget * parent )
: QDialog ( parent )
{
resize ( 600 , 0 ) ;
setWindowTitle ( title ) ;
2023-02-07 15:50:44 +01:00
auto * groupBox = new QGroupBox ( Tr : : tr ( " Specify a revision other than the default? " ) ) ;
2023-02-07 11:48:03 +01:00
groupBox - > setCheckable ( true ) ;
groupBox - > setChecked ( false ) ;
2023-02-07 15:50:44 +01:00
groupBox - > setToolTip ( Tr : : tr ( " Checkout revision, can also be a branch or a tag name. " ) ) ;
2023-02-07 11:48:03 +01:00
m_revisionLineEdit = new QLineEdit ;
auto buttonBox = new QDialogButtonBox ;
buttonBox - > setStandardButtons ( QDialogButtonBox : : Ok | QDialogButtonBox : : Cancel ) ;
connect ( buttonBox , & QDialogButtonBox : : accepted , this , & QDialog : : accept ) ;
connect ( buttonBox , & QDialogButtonBox : : rejected , this , & QDialog : : reject ) ;
2023-04-25 10:15:07 +02:00
using namespace Layouting ;
2023-02-07 11:48:03 +01:00
Form {
2023-02-07 15:50:44 +01:00
Tr : : tr ( " Revision " ) , m_revisionLineEdit , br ,
2023-02-07 11:48:03 +01:00
} . attachTo ( groupBox ) ;
Column {
groupBox ,
buttonBox ,
} . attachTo ( this ) ;
}
2016-11-16 12:51:32 -06:00
} // namespace Internal
} // namespace Fossil
# ifdef WITH_TESTS
# include <QTest>
void Fossil : : Internal : : FossilPlugin : : testDiffFileResolving_data ( )
{
QTest : : addColumn < QByteArray > ( " header " ) ;
QTest : : addColumn < QByteArray > ( " fileName " ) ;
QTest : : newRow ( " New " ) < < QByteArray (
" ADDED src/plugins/fossil/fossilclient.cpp \n "
" Index: src/plugins/fossil/fossilclient.cpp \n "
" ================================================================== \n "
" --- src/plugins/fossil/fossilclient.cpp \n "
" +++ src/plugins/fossil/fossilclient.cpp \n "
" @@ -0,0 +1,295 @@ \n "
)
< < QByteArray ( " src/plugins/fossil/fossilclient.cpp " ) ;
QTest : : newRow ( " Deleted " ) < < QByteArray (
" DELETED src/plugins/fossil/fossilclient.cpp \n "
" Index: src/plugins/fossil/fossilclient.cpp \n "
" ================================================================== \n "
" --- src/plugins/fossil/fossilclient.cpp \n "
" +++ src/plugins/fossil/fossilclient.cpp \n "
" @@ -1,266 +0,0 @@ \n "
)
< < QByteArray ( " src/plugins/fossil/fossilclient.cpp " ) ;
QTest : : newRow ( " Modified " ) < < QByteArray (
" Index: src/plugins/fossil/fossilclient.cpp \n "
" ================================================================== \n "
" --- src/plugins/fossil/fossilclient.cpp \n "
" +++ src/plugins/fossil/fossilclient.cpp \n "
" @@ -112,22 +112,37 @@ \n "
)
< < QByteArray ( " src/plugins/fossil/fossilclient.cpp " ) ;
}
void Fossil : : Internal : : FossilPlugin : : testDiffFileResolving ( )
{
2020-01-31 14:48:28 +02:00
VcsBase : : VcsBaseEditorWidget : : testDiffFileResolving ( dd - > diffFactory ) ;
2016-11-16 12:51:32 -06:00
}
void Fossil : : Internal : : FossilPlugin : : testLogResolving ( )
{
QByteArray data (
" === 2014-03-08 === \n "
" 22:14:02 [ac6d1129b8] Change scaling algorithm. (user: ninja tags: ninja-fixes-5.1) \n "
" EDITED src/core/scaler.cpp \n "
" 20:23:51 [56d6917c3b] *BRANCH* Add width option (conditional). (user: ninja tags: ninja-fixes-5.1) \n "
" EDITED src/core/scaler.cpp \n "
" EDITED src/core/scaler.h \n "
) ;
2020-01-31 14:48:28 +02:00
VcsBase : : VcsBaseEditorWidget : : testLogResolving ( dd - > fileLogFactory , data , " ac6d1129b8 " , " 56d6917c3b " ) ;
2016-11-16 12:51:32 -06:00
}
# endif