diff --git a/CMakeLists.txt b/CMakeLists.txt index 6905eb7..2508cbb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,7 @@ INCLUDE_DIRECTORIES( ${libMacGitverCore_includes} ) +ADD_SUBDIRECTORY( CustomCommands ) ADD_SUBDIRECTORY( History ) ADD_SUBDIRECTORY( GitConfig ) ADD_SUBDIRECTORY( RefsViews ) diff --git a/CustomCommands/CMakeLists.txt b/CustomCommands/CMakeLists.txt new file mode 100644 index 0000000..e91c3c8 --- /dev/null +++ b/CustomCommands/CMakeLists.txt @@ -0,0 +1,53 @@ + +PROJECT( MGV_MOD_CUSTOM_COMMANDS ) + +QT_PREPARE( Core Gui Widgets Xml ) + +INCLUDE_DIRECTORIES( + ${MGV_MOD_CUSTOM_COMMANDS_SOURCE_DIR} + ${MGV_MOD_CUSTOM_COMMANDS_BINARY_DIR} +) + +SET( SRC_FILES + + CustomCommandsModule.cpp + CustomCommandListCfgPage.cpp + EditCustomCommandDlg.cpp + CustomCommandDef.cpp +) + +SET( HDR_FILES + + CustomCommandsModule.hpp + CustomCommandListCfgPage.hpp + EditCustomCommandDlg.hpp + CustomCommandDef.hpp +) + +SET( UI_FILES + + EditCustomCommandDlg.ui + CustomCommandListCfgPage.ui +) + +SET( HID_FILES + CustomCommandActions.hid +) + + +HIC( HIC_FILES ${HID_FILES} ) +QT_UIC( UIC_FILES ${UI_FILES} ) +QT_MOC( MOC_FILES ${HDR_FILES} ) + +ADD_MGV_MODULE( + CustomCommands + + ${SRC_FILES} + ${HDR_FILES} + ${MOC_FILES} + ${UIC_FILES} ${UI_FILES} + ${HIC_FILES} ${HID_FILES} +) + +MSVC_SPLIT_SOURCES( ModCustomCommands ) + diff --git a/CustomCommands/CustomCommandActions.hid b/CustomCommands/CustomCommandActions.hid new file mode 100644 index 0000000..4a7ec92 --- /dev/null +++ b/CustomCommands/CustomCommandActions.hid @@ -0,0 +1,44 @@ +/* + * MacGitver + * Copyright (C) 2012-2013 The MacGitver-Developers + * + * (C) Sascha Cunz + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License (Version 2) as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, see . + * + */ + +Ui CustomCommandActions { + + Container CustComRepoAC { + DynamicActionMerger ExecOnBranch + { + Merger onMergeExecuteOnBranch; + }; + }; + + /* This container lands at the bottom part of the 'tools' menu */ + Container CustComAC { + + Menu ExecuteOnRepo { + Text "R&epository"; + Container CustComRepoAC; + }; + + Separator; + DynamicActionMerger ExecGlobally + { + Merger onMergeExecuteGlobally; + }; + + }; + +}; diff --git a/CustomCommands/CustomCommandDef.cpp b/CustomCommands/CustomCommandDef.cpp new file mode 100644 index 0000000..0102f5b --- /dev/null +++ b/CustomCommands/CustomCommandDef.cpp @@ -0,0 +1,178 @@ +/* +* MacGitver +* Copyright (C) 2012-2013 The MacGitver-Developers +* +* (C) Sascha Cunz +* +* This program is free software; you can redistribute it and/or modify it under the terms of the +* GNU General Public License (Version 2) as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without +* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License along with this program; if +* not, see . +* +*/ + +#include +#include + +#include "CustomCommandDef.hpp" + +CustomCommandDef::CustomCommandDef() +{ + newId(); +} + +CustomCommandDef::CustomCommandDef( const QDomElement& elSelf ) +{ + mId = elSelf.attribute( QLatin1String( "Id" ), QUuid::createUuid().toString() ); + + mName = elSelf.attribute( QLatin1String( "Name" ) ); + mRunModal = elSelf.attribute( QLatin1String( "RunModal" ), QLatin1String( "0" ) ) + == QLatin1String( "1" ); + + mRefresh = RefreshType( elSelf.attribute( QLatin1String( "RefreshType" ), + QLatin1String( "0" ) ).toInt() ); + + mExecute = ExecuteOn( elSelf.attribute( QLatin1String( "ExecuteOn" ), + QLatin1String( "0" ) ).toInt() ); + + mWorkDir = elSelf.attribute( QLatin1String( "WD" ) ); + mCustomWorkDir = elSelf.attribute( QLatin1String( "UseWD" ), QLatin1String( "0" ) ) + == QLatin1String( "1" ); + + QDomNode child = elSelf.firstChild(); + if( child.isCDATASection() ) + { + QDomCDATASection cds = child.toCDATASection(); + mCommand = cds.data(); + } + else if( child.isText() ) + { + QDomText txt = child.toText(); + mCommand = txt.data(); + } +} + +CustomCommandDef::CustomCommandDef( const CustomCommandDef& other ) +{ + mId = other.mId; + mName = other.mName; + mCommand = other.mCommand; + mExecute = other.mExecute; + mRunModal = other.mRunModal; + mRefresh = other.mRefresh; + mCustomWorkDir = other.mCustomWorkDir; + mWorkDir = other.mWorkDir; +} + +CustomCommandDef::~CustomCommandDef() +{ +} + +void CustomCommandDef::newId() +{ + mId = QUuid::createUuid().toString(); +} + +QString CustomCommandDef::id() const +{ + return mId; +} + +QString CustomCommandDef::name() const +{ + return mName; +} + +QString CustomCommandDef::command() const +{ + return mCommand; +} + +CustomCommandDef::ExecuteOn CustomCommandDef::executeOn() const +{ + return mExecute; +} + +bool CustomCommandDef::runModal() const +{ + return mRunModal; +} + +CustomCommandDef::RefreshType CustomCommandDef::refreshType() const +{ + return mRefresh; +} + +bool CustomCommandDef::useCustomWorkingDir() const +{ + return mCustomWorkDir; +} + +QString CustomCommandDef::customWorkingDir() const +{ + return mWorkDir; +} + +void CustomCommandDef::setId( const QString& id ) +{ + mId = id; +} + +void CustomCommandDef::setName( const QString& name ) +{ + mName = name; +} + +void CustomCommandDef::setCommand( const QString& command ) +{ + mCommand = command; +} + +void CustomCommandDef::setExecuteOn( CustomCommandDef::ExecuteOn execOn ) +{ + mExecute = execOn; +} + +void CustomCommandDef::setRunModal( bool runModal ) +{ + mRunModal = runModal; +} + +void CustomCommandDef::setRefreshType( CustomCommandDef::RefreshType type ) +{ + mRefresh = type; +} + +void CustomCommandDef::setUseCustomWorkingDir( bool useCustomWorkingDir ) +{ + mCustomWorkDir = useCustomWorkingDir; +} + +void CustomCommandDef::setCustomWorkingDir( const QString& dir ) +{ + mWorkDir = dir; +} + +void CustomCommandDef::saveTo( QDomElement& elParent ) +{ + QDomDocument doc = elParent.ownerDocument(); + QDomElement el = doc.createElement( QLatin1String( "Command" ) ); + + el.setAttribute( QLatin1String( "Name" ), mName ); + el.setAttribute( QLatin1String( "RunModal" ), mRunModal ? 1 : 0 ); + el.setAttribute( QLatin1String( "RefreshType" ), int( mRefresh ) ); + el.setAttribute( QLatin1String( "ExecuteOn" ), int( mExecute ) ); + el.setAttribute( QLatin1String( "UseWD" ), mCustomWorkDir ? 1 : 0 ); + el.setAttribute( QLatin1String( "WD" ), mWorkDir ); + el.setAttribute( QLatin1String( "Id" ), mId ); + + elParent.appendChild( el ); + + QDomCDATASection cmd = doc.createCDATASection( mCommand ); + el.appendChild( cmd ); +} diff --git a/CustomCommands/CustomCommandDef.hpp b/CustomCommands/CustomCommandDef.hpp new file mode 100644 index 0000000..1949ad1 --- /dev/null +++ b/CustomCommands/CustomCommandDef.hpp @@ -0,0 +1,95 @@ +/* +* MacGitver +* Copyright (C) 2012-2013 The MacGitver-Developers +* +* (C) Sascha Cunz +* +* This program is free software; you can redistribute it and/or modify it under the terms of the +* GNU General Public License (Version 2) as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without +* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License along with this program; if +* not, see . +* +*/ + +#ifndef MGV_CUSTOM_COMMANDS_DEF_HPP +#define MGV_CUSTOM_COMMANDS_DEF_HPP + +#include +#include +#include + +class QDomElement; + +class CustomCommandDef : public QSharedData +{ +public: + enum ExecuteOn + { + ExecRootRepo = 1, + ExecSubRepo = 2, + ExecRootOrSubRepo = 3, + ExecBranch = 4, + ExecForEachSubmodule = 5, + ExecForEachSubmoduleDeep = 6, + ExecInWorkingTree = 7, + ExecGlobally = 8 + }; + + enum RefreshType + { + RefreshNever, + RefreshSuccess, + RefreshFailure, + RefreshAlways + }; + +public: + typedef QExplicitlySharedDataPointer< CustomCommandDef > Ptr; + typedef QList< Ptr > List; + +public: + CustomCommandDef(); + CustomCommandDef( const QDomElement& elSelf ); + CustomCommandDef( const CustomCommandDef& other ); + ~CustomCommandDef(); + +public: + QString id() const; + QString name() const; + QString command() const; + ExecuteOn executeOn() const; + bool runModal() const; + RefreshType refreshType() const; + bool useCustomWorkingDir() const; + QString customWorkingDir() const; + + void newId(); + void setId( const QString& id ); + void setName( const QString& name ); + void setCommand( const QString& command ); + void setExecuteOn( ExecuteOn execOn ); + void setRunModal( bool runModal ); + void setRefreshType( RefreshType type ); + void setUseCustomWorkingDir( bool useCustomWorkingDir ); + void setCustomWorkingDir( const QString& dir ); + +public: + void saveTo( QDomElement& elParent ); + +private: + QString mId; + QString mName; + QString mCommand; + ExecuteOn mExecute; + bool mRunModal; + RefreshType mRefresh; + bool mCustomWorkDir; + QString mWorkDir; +}; + +#endif diff --git a/CustomCommands/CustomCommandListCfgPage.cpp b/CustomCommands/CustomCommandListCfgPage.cpp new file mode 100644 index 0000000..1b08b74 --- /dev/null +++ b/CustomCommands/CustomCommandListCfgPage.cpp @@ -0,0 +1,254 @@ +/* + * MacGitver + * Copyright (C) 2012-2013 The MacGitver-Developers + * + * (C) Sascha Cunz + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License (Version 2) as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, see . + * + */ + +#include +#include + +#include "CustomCommandListCfgPage.hpp" +#include "CustomCommandsModule.hpp" +#include "EditCustomCommandDlg.hpp" + +CustomCommandListCfgPage::CustomCommandListCfgPage( ConfigDialog* dlg ) + : ConfigPage( dlg ) +{ + init(); +} + +CustomCommandListCfgPage::~CustomCommandListCfgPage() +{ +} + +void CustomCommandListCfgPage::apply() +{ + CustomCommandsModule::self().setCommands( mCommands ); + setModified( false ); +} + +void CustomCommandListCfgPage::init() +{ + setupUi( this ); + + connect( cmdAdd, SIGNAL(clicked()), this, SLOT(onAdd()) ); + connect( cmdCopy, SIGNAL(clicked()), this, SLOT(onCopy()) ); + connect( cmdEdit, SIGNAL(clicked()), this, SLOT(onEdit()) ); + connect( cmdRemove, SIGNAL(clicked()), this, SLOT(onRemove()) ); + + mModel = new QStandardItemModel( 0, 2, this ); + + mModel->setHorizontalHeaderLabels( QStringList() + << trUtf8( "Command" ) + << trUtf8( "Scope" ) ); + treeView->setModel( mModel ); + + mCommands = CustomCommandsModule::self().commands(); + readCommands(); + + connect( treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), + this, SLOT(onSelectionChanged()) ); + onSelectionChanged(); +} + +QByteArray CustomCommandListCfgPage::pageId() const +{ + return "Commands"; +} + +QByteArray CustomCommandListCfgPage::groupId() const +{ + return "General"; +} + +QString CustomCommandListCfgPage::pageName() const +{ + return trUtf8( "Commands" ); +} + +QString CustomCommandListCfgPage::groupName() const +{ + return trUtf8( "Gerneral" ); +} + +void CustomCommandListCfgPage::onSelectionChanged() +{ + QModelIndex idx = treeView->selectionModel()->currentIndex(); + + cmdEdit->setEnabled( idx.isValid() ); + cmdCopy->setEnabled( idx.isValid() ); + cmdRemove->setEnabled( idx.isValid() ); +} + +void CustomCommandListCfgPage::onAdd() +{ + EditCustomCommandDlg d( this, trUtf8( "Create custom command" ) ); + if( d.exec() ) + { + CustomCommandDef::Ptr cmd = d.getData( false ); + mCommands.append( cmd ); + addCommand( cmd, true ); + setModified(); + } +} + +void CustomCommandListCfgPage::onEdit() +{ + QModelIndex idx = treeView->selectionModel()->currentIndex(); + if( !idx.isValid() ) + { + return; + } + + QStandardItem* parent = mModel->invisibleRootItem(); + QStandardItem* it = parent->child( idx.row() ); + Q_ASSERT( it ); + + QString id = it->data().toString(); + CustomCommandDef::Ptr cmd = findCommand( id ); + Q_ASSERT( cmd ); + + EditCustomCommandDlg d( this, trUtf8( "Edit custom command" ), cmd ); + if( d.exec() ) + { + d.getData( true ); + updateCommand( cmd ); + setModified(); + } +} + +void CustomCommandListCfgPage::onRemove() +{ + QModelIndex idx = treeView->selectionModel()->currentIndex(); + if( !idx.isValid() ) + { + return; + } + + QStandardItem* parent = mModel->invisibleRootItem(); + QStandardItem* it = parent->child( idx.row() ); + Q_ASSERT( it ); + + QString id = it->data().toString(); + for( int i = 0; i < mCommands.count(); ++i ) + { + if( mCommands[ i ]->id() == id ) + { + mCommands.removeAt( i ); + setModified(); + + parent->removeRow( idx.row() ); + return; + } + } +} + +void CustomCommandListCfgPage::onCopy() +{ + QModelIndex idx = treeView->selectionModel()->currentIndex(); + if( !idx.isValid() ) + { + return; + } + + QStandardItem* parent = mModel->invisibleRootItem(); + QStandardItem* it = parent->child( idx.row() ); + Q_ASSERT( it ); + + QString id = it->data().toString(); + CustomCommandDef::Ptr cmd = findCommand( id ); + Q_ASSERT( cmd ); + + EditCustomCommandDlg d( this, trUtf8( "Copy custom command" ), cmd ); + if( d.exec() ) + { + cmd = d.getData( false ); + mCommands.append( cmd ); + addCommand( cmd, true ); + setModified(); + } +} + +void CustomCommandListCfgPage::readCommands() +{ + foreach( CustomCommandDef::Ptr cmd, mCommands ) + { + addCommand( cmd ); + } +} + +QString CustomCommandListCfgPage::execText( CustomCommandDef::ExecuteOn exec ) +{ + switch( exec ) + { + case CustomCommandDef::ExecBranch: return trUtf8( "Branch" ); + case CustomCommandDef::ExecRootRepo: return trUtf8( "Repository (Root)" ); + case CustomCommandDef::ExecSubRepo: return trUtf8( "Repository (Submodules)" ); + case CustomCommandDef::ExecRootOrSubRepo: return trUtf8( "Repository (Root and" + " Submodules)" ); + case CustomCommandDef::ExecForEachSubmodule: return trUtf8( "For each submodule" ); + case CustomCommandDef::ExecForEachSubmoduleDeep: return trUtf8( "For each submodule" + " (Recursive)" ); + case CustomCommandDef::ExecGlobally: return trUtf8( "Global Command" ); + case CustomCommandDef::ExecInWorkingTree: return trUtf8( "In working tree" ); + default: return trUtf8( "Unknown" ); + } +} + +void CustomCommandListCfgPage::addCommand( CustomCommandDef::Ptr cmd, bool select ) +{ + QList< QStandardItem* > row; + row << new QStandardItem( cmd->name() ); + row << new QStandardItem( execText( cmd->executeOn() ) ); + row[ 0 ]->setData( cmd->id() ); + mModel->appendRow( row ); +} + +void CustomCommandListCfgPage::updateCommand( CustomCommandDef::Ptr cmd ) +{ + if( !cmd ) + { + return; + } + + QString id = cmd->id(); + QStandardItem* parent = mModel->invisibleRootItem(); + for( int i = 0; i < parent->rowCount(); ++i ) + { + QStandardItem* it = parent->child( i ); + if( it->data().toString() == id ) + { + it->setText( cmd->name() ); + it = parent->child( i, 1 ); + it->setText( execText( cmd->executeOn() ) ); + return; + } + } + + addCommand( cmd ); +} + +CustomCommandDef::Ptr CustomCommandListCfgPage::findCommand( const QString& id ) const +{ + for( int i = 0; i < mCommands.count(); ++i ) + { + if( mCommands[ i ]->id() == id ) + { + return mCommands[ i ]; + } + } + + return CustomCommandDef::Ptr(); +} diff --git a/CustomCommands/CustomCommandListCfgPage.hpp b/CustomCommands/CustomCommandListCfgPage.hpp new file mode 100644 index 0000000..2bbb3fc --- /dev/null +++ b/CustomCommands/CustomCommandListCfgPage.hpp @@ -0,0 +1,66 @@ +/* + * MacGitver + * Copyright (C) 2012-2013 The MacGitver-Developers + * + * (C) Sascha Cunz + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License (Version 2) as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, see . + * + */ + +#ifndef MGV_CUSCOM_CONFIG_PAGE_HPP +#define MGV_CUSCOM_CONFIG_PAGE_HPP + +#include "libMacGitverCore/Config/Ui/ConfigDialog.hpp" + +#include "CustomCommandDef.hpp" +#include "ui_CustomCommandListCfgPage.h" + +class QStandardItemModel; + +class CustomCommandListCfgPage : public ConfigPage, Ui::CustomCommandListCfgPage +{ + Q_OBJECT + +public: + CustomCommandListCfgPage( ConfigDialog* dlg ); + ~CustomCommandListCfgPage(); + +public: + void apply(); + void init(); + + QByteArray pageId() const; + QByteArray groupId() const; + + QString pageName() const; + QString groupName() const; + +private slots: + void onAdd(); + void onEdit(); + void onRemove(); + void onCopy(); + void onSelectionChanged(); + +private: + void readCommands(); + CustomCommandDef::Ptr findCommand( const QString& id ) const; + void addCommand( CustomCommandDef::Ptr cmd, bool select = false ); + void updateCommand( CustomCommandDef::Ptr cmd ); + static QString execText( CustomCommandDef::ExecuteOn exec ); + +private: + CustomCommandDef::List mCommands; + QStandardItemModel* mModel; +}; + +#endif diff --git a/CustomCommands/CustomCommandListCfgPage.ui b/CustomCommands/CustomCommandListCfgPage.ui new file mode 100644 index 0000000..789f5f6 --- /dev/null +++ b/CustomCommands/CustomCommandListCfgPage.ui @@ -0,0 +1,81 @@ + + + CustomCommandListCfgPage + + + + 0 + 0 + 549 + 300 + + + + + + + &Add + + + + + + + &Edit + + + + + + + &Copy + + + + + + + &Remove + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QAbstractItemView::NoEditTriggers + + + false + + + false + + + true + + + false + + + true + + + + + + + + diff --git a/CustomCommands/CustomCommandsModule.cpp b/CustomCommands/CustomCommandsModule.cpp new file mode 100644 index 0000000..bcbb4cf --- /dev/null +++ b/CustomCommands/CustomCommandsModule.cpp @@ -0,0 +1,130 @@ +/* + * MacGitver + * Copyright (C) 2012-2013 The MacGitver-Developers + * + * (C) Sascha Cunz + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License (Version 2) as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, see . + * + */ + +#include +#include +#include +#include +#include + +#include "libHeaven/App/Application.hpp" + +#include "CustomCommandsModule.hpp" +#include "CustomCommandListCfgPage.hpp" + +CustomCommandsModule::CustomCommandsModule() +{ +} + +CustomCommandsModule& CustomCommandsModule::self() +{ + Q_ASSERT( sSelf ); + return *sSelf; +} + +CustomCommandsModule* CustomCommandsModule::sSelf = NULL; + +void CustomCommandsModule::initialize() +{ + Q_ASSERT( sSelf == NULL ); + sSelf = this; + setupActions( this ); + loadCommands(); + + acCustComAC->mergeInto( "CustomToolsMP" ); +} + +void CustomCommandsModule::deinitialize() +{ + sSelf = NULL; +} + +void CustomCommandsModule::setupConfigPages( ConfigDialog* dialog ) +{ + dialog->addPage( new CustomCommandListCfgPage( dialog ) ); +} + +void CustomCommandsModule::onMergeExecuteOnBranch( Heaven::DynamicActionMerger* dam ) +{ + dam->addAction( new QAction( QLatin1String( "&Foo" ), this ) ); +} + +void CustomCommandsModule::loadCommands() +{ + QString fn = commandsFileName(); + QFile f( fn ); + if( !f.open( QFile::ReadOnly ) ) + { + return; + } + + QDomDocument doc; + doc.setContent( &f ); + QDomElement el = doc.documentElement().firstChildElement(); + while( el.isElement() ) + { + CustomCommandDef::Ptr cmd = CustomCommandDef::Ptr( new CustomCommandDef( el ) ); + mCommands.append( cmd ); + + el = el.nextSiblingElement(); + } +} + +void CustomCommandsModule::saveCommands() +{ + QString fn = commandsFileName(); + + QDomDocument doc( QLatin1String( "CustomCommands" ) ); + QDomElement elRoot = doc.createElement( QLatin1String( "CustomCommands" ) ); + doc.appendChild( elRoot ); + + foreach( CustomCommandDef::Ptr cmd, mCommands ) + { + cmd->saveTo( elRoot ); + } + + QString xml = doc.toString(); + + QFile f( fn ); + if( !f.open( QFile::WriteOnly ) ) + { + return; + } + f.write( xml.toUtf8() ); +} + +QString CustomCommandsModule::commandsFileName() const +{ + QString base = Heaven::Application::dataPath(); + return base % QLatin1Literal( "/commands.xml" ); +} + +CustomCommandDef::List CustomCommandsModule::commands() const +{ + return mCommands; +} + +void CustomCommandsModule::setCommands( const CustomCommandDef::List& commands ) +{ + mCommands = commands; + saveCommands(); +} + +#if QT_VERSION < 0x050000 +Q_EXPORT_PLUGIN2( CustomCommands, CustomCommandsModule ) +#endif diff --git a/CustomCommands/CustomCommandsModule.hpp b/CustomCommands/CustomCommandsModule.hpp new file mode 100644 index 0000000..ccc80d1 --- /dev/null +++ b/CustomCommands/CustomCommandsModule.hpp @@ -0,0 +1,57 @@ +/* + * MacGitver + * Copyright (C) 2012-2013 The MacGitver-Developers + * + * (C) Sascha Cunz + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License (Version 2) as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, see . + * + */ + +#ifndef MGV_MODULE_CUSTOM_COMMANDS_HPP +#define MGV_MODULE_CUSTOM_COMMANDS_HPP + +#include "libMacGitverCore/MacGitver/Module.h" + +#include "CustomCommandDef.hpp" +#include "hic_CustomCommandActions.h" + +class CustomCommandsModule : public Module, private CustomCommandActions +{ + Q_OBJECT + Q_PLUGIN_METADATA( IID "org.macgitver.Module/0.1" FILE "Module.json" ) + Q_INTERFACES( Module ) +public: + CustomCommandsModule(); + static CustomCommandsModule& self(); + +public: + void initialize(); + void deinitialize(); + void setupConfigPages( ConfigDialog* dialog ); + + CustomCommandDef::List commands() const; + void setCommands( const CustomCommandDef::List& commands ); + +private slots: + void onMergeExecuteOnBranch( Heaven::DynamicActionMerger* dam ); + +private: + void loadCommands(); + void saveCommands(); + QString commandsFileName() const; + +private: + static CustomCommandsModule* sSelf; + CustomCommandDef::List mCommands; +}; + +#endif diff --git a/CustomCommands/EditCustomCommandDlg.cpp b/CustomCommands/EditCustomCommandDlg.cpp new file mode 100644 index 0000000..10b9590 --- /dev/null +++ b/CustomCommands/EditCustomCommandDlg.cpp @@ -0,0 +1,105 @@ +/* + * MacGitver + * Copyright (C) 2012-2013 The MacGitver-Developers + * + * (C) Sascha Cunz + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License (Version 2) as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, see . + * + */ + +#include + +#include "EditCustomCommandDlg.hpp" + +EditCustomCommandDlg::EditCustomCommandDlg( QWidget* parent, + const QString& title, + CustomCommandDef::Ptr cmdTemplate ) + : QDialog( parent ) + , mCmdTemplate( cmdTemplate ) +{ + init(); + setWindowTitle( title ); +} + +void EditCustomCommandDlg::init() +{ + setupUi( this ); + + mRefreshGroup = new QButtonGroup( this ); + mRefreshGroup->addButton( chkRefreshAlways, CustomCommandDef::RefreshAlways ); + mRefreshGroup->addButton( chkRefreshFailure, CustomCommandDef::RefreshSuccess ); + mRefreshGroup->addButton( chkRefreshNever, CustomCommandDef::RefreshNever ); + mRefreshGroup->addButton( chkRefreshSuccess, CustomCommandDef::RefreshSuccess ); + + mRunGroup = new QButtonGroup( this ); + mRunGroup->addButton( chkRunBackground, false ); + mRunGroup->addButton( chkRunModal, true ); + + chkRefreshNever->setChecked( true ); + chkRunModal->setChecked( true ); + + txtWorkingDirectory->setEnabled( false ); + connect( chkCustomWD, SIGNAL(toggled(bool)), txtWorkingDirectory, SLOT(setEnabled(bool)) ); + + cboContext->addItem( trUtf8( "Execute on Repository (root)" ), + CustomCommandDef::ExecRootRepo ); + cboContext->addItem( trUtf8( "Execute on Repository (submodule)" ), + CustomCommandDef::ExecSubRepo ); + cboContext->addItem( trUtf8( "Execute on Repository (root or submodule)" ), + CustomCommandDef::ExecRootOrSubRepo ); + cboContext->addItem( trUtf8( "Execute for all submodules" ), + CustomCommandDef::ExecForEachSubmodule ); + cboContext->addItem( trUtf8( "Execute for all submodules (recursive)" ), + CustomCommandDef::ExecForEachSubmoduleDeep ); + cboContext->addItem( trUtf8( "Execute on Branch" ), + CustomCommandDef::ExecBranch ); + cboContext->addItem( trUtf8( "Execute in Working tree" ), + CustomCommandDef::ExecInWorkingTree ); + cboContext->addItem( trUtf8( "Execute gobally" ), + CustomCommandDef::ExecGlobally ); + + loadTemplate(); +} + +void EditCustomCommandDlg::loadTemplate() +{ + if( mCmdTemplate.data() ) + { + txtCommandName->setText( mCmdTemplate->name() ); + txtCommands->setPlainText( mCmdTemplate->command() ); + cboContext->setCurrentIndex( cboContext->findData( mCmdTemplate->executeOn() ) ); + mRefreshGroup->button( mCmdTemplate->refreshType() )->setChecked( true ); + mRunGroup->button( mCmdTemplate->runModal() )->setChecked( true ); + chkCustomWD->setChecked( mCmdTemplate->useCustomWorkingDir() ); + txtWorkingDirectory->setText( mCmdTemplate->customWorkingDir() ); + } +} + +CustomCommandDef::Ptr EditCustomCommandDlg::getData( bool overWriteTemplate ) +{ + CustomCommandDef::Ptr data = mCmdTemplate; + if( !overWriteTemplate ) + { + data = new CustomCommandDef; + } + + data->setName( txtCommandName->text() ); + data->setCommand( txtCommands->toPlainText() ); + data->setRunModal( chkRunModal->isChecked() ); + data->setRefreshType( CustomCommandDef::RefreshType( mRefreshGroup->checkedId() ) ); + data->setExecuteOn( CustomCommandDef::ExecuteOn( cboContext->itemData( + cboContext->currentIndex() ).toInt() ) ); + data->setUseCustomWorkingDir( chkCustomWD->isChecked() ); + data->setCustomWorkingDir( txtWorkingDirectory->text() ); + + return data; +} diff --git a/CustomCommands/EditCustomCommandDlg.hpp b/CustomCommands/EditCustomCommandDlg.hpp new file mode 100644 index 0000000..58b196d --- /dev/null +++ b/CustomCommands/EditCustomCommandDlg.hpp @@ -0,0 +1,49 @@ +/* + * MacGitver + * Copyright (C) 2012-2013 The MacGitver-Developers + * + * (C) Sascha Cunz + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License (Version 2) as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if + * not, see . + * + */ + +#ifndef MGV_CUSCOM_EDIT_DLG_HPP +#define MGV_CUSCOM_EDIT_DLG_HPP + +#include "ui_EditCustomCommandDlg.h" + +#include "CustomCommandDef.hpp" + +class EditCustomCommandDlg : public QDialog, private Ui::EditCustomCommandDlg +{ + Q_OBJECT +public: + EditCustomCommandDlg( QWidget* parent, + const QString& title, + CustomCommandDef::Ptr cmdTemplate = CustomCommandDef::Ptr() ); + +private: + void init(); + void loadTemplate(); + +public: + CustomCommandDef::Ptr getData( bool overWriteTemplate = true ); + +private: + CustomCommandDef::Ptr mCmdTemplate; + QButtonGroup* mRunGroup; + QButtonGroup* mRefreshGroup; +}; + +#endif + + diff --git a/CustomCommands/EditCustomCommandDlg.ui b/CustomCommands/EditCustomCommandDlg.ui new file mode 100644 index 0000000..864419f --- /dev/null +++ b/CustomCommands/EditCustomCommandDlg.ui @@ -0,0 +1,268 @@ + + + EditCustomCommandDlg + + + + 0 + 0 + 548 + 484 + + + + + + + Custom Command + + + + + + + 0 + 0 + + + + Name: + + + txtCommandName + + + + + + + + 0 + 0 + + + + true + + + + + + + + 0 + 0 + + + + Context: + + + cboContext + + + + + + + + 0 + 0 + + + + Refresh: + + + + + + + + + Never + + + + + + + On Failure + + + + + + + On Success + + + + + + + Always + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 0 + + + + Run: + + + + + + + + + modal + + + + + + + in background + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Custom working dir: + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + LineEdit + QLineEdit +
libMacGitverCore/Widgets/LineEdit.h
+
+
+ + txtCommandName + cboContext + chkRefreshNever + chkRefreshFailure + chkRefreshSuccess + chkRefreshAlways + chkRunModal + chkRunBackground + chkCustomWD + txtWorkingDirectory + txtCommands + buttonBox + + + + + buttonBox + accepted() + EditCustomCommandDlg + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + EditCustomCommandDlg + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/CustomCommands/Module.json b/CustomCommands/Module.json new file mode 100644 index 0000000..64ecfce --- /dev/null +++ b/CustomCommands/Module.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "CustomCommands" ] +} diff --git a/Repository/RepoTreeViewCtxMenu.hid b/Repository/RepoTreeViewCtxMenu.hid index cbedc14..d0ff0ef 100644 --- a/Repository/RepoTreeViewCtxMenu.hid +++ b/Repository/RepoTreeViewCtxMenu.hid @@ -34,6 +34,8 @@ Ui RepoTreeViewCtxMenu { Action Activate; Separator; + MergePlace RepoRootCtx; + Separator; Action Close; }; @@ -41,6 +43,8 @@ Ui RepoTreeViewCtxMenu { Menu CtxMenuSMRepo { Action Activate; + Separator; + MergePlace RepoSubCtx; };