bazaarplugin.cpp 25.9 KB
Newer Older
cerf's avatar
cerf committed
1 2 3 4 5 6
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Hugues Delorme
**
Eike Ziller's avatar
Eike Ziller committed
7
** Contact: http://www.qt-project.org/
cerf's avatar
cerf committed
8 9 10 11
**
**
** GNU Lesser General Public License Usage
**
hjk's avatar
hjk committed
12 13 14 15 16 17
** 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.
cerf's avatar
cerf committed
18 19
**
** In addition, as a special exception, Nokia gives you certain additional
hjk's avatar
hjk committed
20
** rights. These rights are described in the Nokia Qt LGPL Exception
cerf's avatar
cerf committed
21 22
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
23 24 25 26 27
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
cerf's avatar
cerf committed
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
**
**************************************************************************/

#include "bazaarplugin.h"
#include "constants.h"
#include "bazaarclient.h"
#include "bazaarcontrol.h"
#include "optionspage.h"
#include "bazaarcommitwidget.h"
#include "bazaareditor.h"
#include "pullorpushdialog.h"
#include "commiteditor.h"
#include "clonewizard.h"

#include "ui_revertdialog.h"

#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/command.h>
47
#include <coreplugin/id.h>
cerf's avatar
cerf committed
48 49 50
#include <coreplugin/vcsmanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
51
#include <coreplugin/documentmanager.h>
cerf's avatar
cerf committed
52 53 54 55 56 57 58 59 60 61 62 63 64
#include <coreplugin/editormanager/editormanager.h>

#include <locator/commandlocator.h>

#include <utils/parameteraction.h>
#include <utils/qtcassert.h>

#include <vcsbase/basevcseditorfactory.h>
#include <vcsbase/basevcssubmiteditorfactory.h>
#include <vcsbase/vcsbasesubmiteditor.h>
#include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseoutputwindow.h>

65 66 67 68
#include <QtPlugin>
#include <QAction>
#include <QMenu>
#include <QMainWindow>
hjk's avatar
hjk committed
69
#include <QDebug>
70 71 72 73 74
#include <QtGlobal>
#include <QDir>
#include <QDialog>
#include <QFileDialog>
#include <QTemporaryFile>
cerf's avatar
cerf committed
75 76 77 78 79


using namespace Bazaar::Internal;
using namespace Bazaar;

hjk's avatar
hjk committed
80
static const VcsBase::VcsBaseEditorParameters editorParameters[] = {
cerf's avatar
cerf committed
81
    {
hjk's avatar
hjk committed
82
        VcsBase::RegularCommandOutput, //type
cerf's avatar
cerf committed
83 84 85 86 87 88
        Constants::COMMANDLOG_ID, // id
        Constants::COMMANDLOG_DISPLAY_NAME, // display name
        Constants::COMMANDLOG, // context
        Constants::COMMANDAPP, // mime type
        Constants::COMMANDEXT}, //extension

hjk's avatar
hjk committed
89
    {   VcsBase::LogOutput,
cerf's avatar
cerf committed
90 91 92 93 94 95
        Constants::FILELOG_ID,
        Constants::FILELOG_DISPLAY_NAME,
        Constants::FILELOG,
        Constants::LOGAPP,
        Constants::LOGEXT},

hjk's avatar
hjk committed
96
    {    VcsBase::AnnotateOutput,
cerf's avatar
cerf committed
97 98 99 100 101 102
         Constants::ANNOTATELOG_ID,
         Constants::ANNOTATELOG_DISPLAY_NAME,
         Constants::ANNOTATELOG,
         Constants::ANNOTATEAPP,
         Constants::ANNOTATEEXT},

hjk's avatar
hjk committed
103
    {   VcsBase::DiffOutput,
cerf's avatar
cerf committed
104 105 106 107 108 109 110
        Constants::DIFFLOG_ID,
        Constants::DIFFLOG_DISPLAY_NAME,
        Constants::DIFFLOG,
        Constants::DIFFAPP,
        Constants::DIFFEXT}
};

hjk's avatar
hjk committed
111
static const VcsBase::VcsBaseSubmitEditorParameters submitEditorParameters = {
cerf's avatar
cerf committed
112 113 114 115 116 117 118 119 120
    Constants::COMMITMIMETYPE,
    Constants::COMMIT_ID,
    Constants::COMMIT_DISPLAY_NAME,
    Constants::COMMIT_ID
};


BazaarPlugin *BazaarPlugin::m_instance = 0;

121
BazaarPlugin::BazaarPlugin()
hjk's avatar
hjk committed
122
    : VcsBase::VcsBasePlugin(QLatin1String(Constants::COMMIT_ID)),
123 124 125 126 127 128 129
      m_optionsPage(0),
      m_client(0),
      m_commandLocator(0),
      m_changeLog(0),
      m_addAction(0),
      m_deleteAction(0),
      m_menuAction(0)
cerf's avatar
cerf committed
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
{
    m_instance = this;
}

BazaarPlugin::~BazaarPlugin()
{
    if (m_client) {
        delete m_client;
        m_client = 0;
    }

    deleteCommitLog();

    m_instance = 0;
}

146
bool BazaarPlugin::initialize(const QStringList &arguments, QString *errorMessage)
cerf's avatar
cerf committed
147
{
148 149 150
    Q_UNUSED(arguments);
    Q_UNUSED(errorMessage);

hjk's avatar
hjk committed
151
    typedef VcsBase::VcsEditorFactory<BazaarEditor> BazaarEditorFactory;
cerf's avatar
cerf committed
152

153
    m_client = new BazaarClient(&m_bazaarSettings);
154
    initializeVcs(new BazaarControl(m_client));
cerf's avatar
cerf committed
155 156 157

    m_optionsPage = new OptionsPage();
    addAutoReleasedObject(m_optionsPage);
hjk's avatar
hjk committed
158
    m_bazaarSettings.readSettings(Core::ICore::settings());
cerf's avatar
cerf committed
159 160 161 162

    connect(m_client, SIGNAL(changed(QVariant)), versionControl(), SLOT(changed(QVariant)));

    static const char *describeSlot = SLOT(view(QString,QString));
hjk's avatar
hjk committed
163
    const int editorCount = sizeof(editorParameters) / sizeof(VcsBase::VcsBaseEditorParameters);
cerf's avatar
cerf committed
164 165 166
    for (int i = 0; i < editorCount; i++)
        addAutoReleasedObject(new BazaarEditorFactory(editorParameters + i, m_client, describeSlot));

hjk's avatar
hjk committed
167
    addAutoReleasedObject(new VcsBase::VcsSubmitEditorFactory<CommitEditor>(&submitEditorParameters));
cerf's avatar
cerf committed
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199

    addAutoReleasedObject(new CloneWizard);

    const QString prefix = QLatin1String("bzr");
    m_commandLocator = new Locator::CommandLocator(QLatin1String("Bazaar"), prefix, prefix);
    addAutoReleasedObject(m_commandLocator);

    createMenu();

    createSubmitEditorActions();

    return true;
}

BazaarPlugin *BazaarPlugin::instance()
{
    return m_instance;
}

BazaarClient *BazaarPlugin::client() const
{
    return m_client;
}

const BazaarSettings &BazaarPlugin::settings() const
{
    return m_bazaarSettings;
}

void BazaarPlugin::setSettings(const BazaarSettings &settings)
{
    if (settings != m_bazaarSettings) {
cerf's avatar
cerf committed
200 201 202 203
        const bool userIdChanged = !m_bazaarSettings.sameUserId(settings);
        m_bazaarSettings = settings;
        if (userIdChanged)
            client()->synchronousSetUserId();
204
        static_cast<BazaarControl *>(versionControl())->emitConfigurationChanged();
cerf's avatar
cerf committed
205 206 207 208 209 210 211 212
    }
}

void BazaarPlugin::createMenu()
{
    Core::Context context(Core::Constants::C_GLOBAL);

    // Create menu item for Bazaar
Eike Ziller's avatar
Eike Ziller committed
213
    m_bazaarContainer = Core::ActionManager::createMenu(Core::Id("Bazaar.BazaarMenu"));
cerf's avatar
cerf committed
214 215 216 217
    QMenu *menu = m_bazaarContainer->menu();
    menu->setTitle(tr("Bazaar"));

    createFileActions(context);
218
    m_bazaarContainer->addSeparator(context);
cerf's avatar
cerf committed
219
    createDirectoryActions(context);
220
    m_bazaarContainer->addSeparator(context);
cerf's avatar
cerf committed
221
    createRepositoryActions(context);
222
    m_bazaarContainer->addSeparator(context);
cerf's avatar
cerf committed
223 224

    // Request the Tools menu and add the Bazaar menu to it
Eike Ziller's avatar
Eike Ziller committed
225
    Core::ActionContainer *toolsMenu = Core::ActionManager::actionContainer(Core::Id(Core::Constants::M_TOOLS));
cerf's avatar
cerf committed
226 227 228 229 230 231 232 233 234
    toolsMenu->addMenu(m_bazaarContainer);
    m_menuAction = m_bazaarContainer->menu()->menuAction();
}

void BazaarPlugin::createFileActions(const Core::Context &context)
{
    Core::Command *command;

    m_annotateFile = new Utils::ParameterAction(tr("Annotate Current File"), tr("Annotate \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
Eike Ziller's avatar
Eike Ziller committed
235
    command = Core::ActionManager::registerAction(m_annotateFile, Core::Id(Constants::ANNOTATE), context);
cerf's avatar
cerf committed
236 237 238 239 240 241
    command->setAttribute(Core::Command::CA_UpdateText);
    connect(m_annotateFile, SIGNAL(triggered()), this, SLOT(annotateCurrentFile()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

    m_diffFile = new Utils::ParameterAction(tr("Diff Current File"), tr("Diff \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
Eike Ziller's avatar
Eike Ziller committed
242
    command = Core::ActionManager::registerAction(m_diffFile, Core::Id(Constants::DIFF), context);
cerf's avatar
cerf committed
243
    command->setAttribute(Core::Command::CA_UpdateText);
244
    command->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+Z,Meta+D") : tr("ALT+Z,Alt+D")));
cerf's avatar
cerf committed
245 246 247 248 249
    connect(m_diffFile, SIGNAL(triggered()), this, SLOT(diffCurrentFile()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

    m_logFile = new Utils::ParameterAction(tr("Log Current File"), tr("Log \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
Eike Ziller's avatar
Eike Ziller committed
250
    command = Core::ActionManager::registerAction(m_logFile, Core::Id(Constants::LOG), context);
cerf's avatar
cerf committed
251
    command->setAttribute(Core::Command::CA_UpdateText);
252
    command->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+Z,Meta+L") : tr("ALT+Z,Alt+L")));
cerf's avatar
cerf committed
253 254 255 256 257
    connect(m_logFile, SIGNAL(triggered()), this, SLOT(logCurrentFile()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

    m_statusFile = new Utils::ParameterAction(tr("Status Current File"), tr("Status \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
Eike Ziller's avatar
Eike Ziller committed
258
    command = Core::ActionManager::registerAction(m_statusFile, Core::Id(Constants::STATUS), context);
cerf's avatar
cerf committed
259
    command->setAttribute(Core::Command::CA_UpdateText);
260
    command->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+Z,Meta+S") : tr("ALT+Z,Alt+S")));
cerf's avatar
cerf committed
261 262 263 264
    connect(m_statusFile, SIGNAL(triggered()), this, SLOT(statusCurrentFile()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

265
    m_bazaarContainer->addSeparator(context);
cerf's avatar
cerf committed
266 267

    m_addAction = new Utils::ParameterAction(tr("Add"), tr("Add \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
Eike Ziller's avatar
Eike Ziller committed
268
    command = Core::ActionManager::registerAction(m_addAction, Core::Id(Constants::ADD), context);
cerf's avatar
cerf committed
269 270 271 272 273 274
    command->setAttribute(Core::Command::CA_UpdateText);
    connect(m_addAction, SIGNAL(triggered()), this, SLOT(addCurrentFile()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

    m_deleteAction = new Utils::ParameterAction(tr("Delete..."), tr("Delete \"%1\"..."), Utils::ParameterAction::EnabledWithParameter, this);
Eike Ziller's avatar
Eike Ziller committed
275
    command = Core::ActionManager::registerAction(m_deleteAction, Core::Id(Constants::DELETE), context);
cerf's avatar
cerf committed
276 277 278 279 280 281
    command->setAttribute(Core::Command::CA_UpdateText);
    connect(m_deleteAction, SIGNAL(triggered()), this, SLOT(promptToDeleteCurrentFile()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

    m_revertFile = new Utils::ParameterAction(tr("Revert Current File..."), tr("Revert \"%1\"..."), Utils::ParameterAction::EnabledWithParameter, this);
Eike Ziller's avatar
Eike Ziller committed
282
    command = Core::ActionManager::registerAction(m_revertFile, Core::Id(Constants::REVERT), context);
cerf's avatar
cerf committed
283 284 285 286 287 288 289 290
    command->setAttribute(Core::Command::CA_UpdateText);
    connect(m_revertFile, SIGNAL(triggered()), this, SLOT(revertCurrentFile()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);
}

void BazaarPlugin::addCurrentFile()
{
hjk's avatar
hjk committed
291
    const VcsBase::VcsBasePluginState state = currentState();
Tobias Hunger's avatar
Tobias Hunger committed
292 293
    QTC_ASSERT(state.hasFile(), return);
    m_client->synchronousAdd(state.currentFileTopLevel(), state.relativeCurrentFile());
cerf's avatar
cerf committed
294 295 296 297
}

void BazaarPlugin::annotateCurrentFile()
{
hjk's avatar
hjk committed
298
    const VcsBase::VcsBasePluginState state = currentState();
Tobias Hunger's avatar
Tobias Hunger committed
299 300
    QTC_ASSERT(state.hasFile(), return);
    m_client->annotate(state.currentFileTopLevel(), state.relativeCurrentFile());
cerf's avatar
cerf committed
301 302 303 304
}

void BazaarPlugin::diffCurrentFile()
{
hjk's avatar
hjk committed
305
    const VcsBase::VcsBasePluginState state = currentState();
Tobias Hunger's avatar
Tobias Hunger committed
306 307
    QTC_ASSERT(state.hasFile(), return);
    m_client->diff(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile()));
cerf's avatar
cerf committed
308 309 310 311
}

void BazaarPlugin::logCurrentFile()
{
hjk's avatar
hjk committed
312
    const VcsBase::VcsBasePluginState state = currentState();
Tobias Hunger's avatar
Tobias Hunger committed
313
    QTC_ASSERT(state.hasFile(), return);
314
    m_client->log(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile()),
315
                  QStringList(), true);
cerf's avatar
cerf committed
316 317 318 319
}

void BazaarPlugin::revertCurrentFile()
{
hjk's avatar
hjk committed
320
    const VcsBase::VcsBasePluginState state = currentState();
cerf's avatar
cerf committed
321 322 323 324 325 326 327 328 329 330 331 332 333 334
    QTC_ASSERT(state.hasFile(), return);

    QDialog dialog;
    Ui::RevertDialog revertUi;
    revertUi.setupUi(&dialog);
    if (dialog.exec() != QDialog::Accepted)
        return;
    m_client->revertFile(state.currentFileTopLevel(),
                         state.relativeCurrentFile(),
                         revertUi.revisionLineEdit->text());
}

void BazaarPlugin::statusCurrentFile()
{
hjk's avatar
hjk committed
335
    const VcsBase::VcsBasePluginState state = currentState();
Tobias Hunger's avatar
Tobias Hunger committed
336 337
    QTC_ASSERT(state.hasFile(), return);
    m_client->status(state.currentFileTopLevel(), state.relativeCurrentFile());
cerf's avatar
cerf committed
338 339 340 341 342 343 344 345 346
}

void BazaarPlugin::createDirectoryActions(const Core::Context &context)
{
    QAction *action;
    Core::Command *command;

    action = new QAction(tr("Diff"), this);
    m_repositoryActionList.append(action);
Eike Ziller's avatar
Eike Ziller committed
347
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::DIFFMULTI), context);
cerf's avatar
cerf committed
348 349 350 351 352 353
    connect(action, SIGNAL(triggered()), this, SLOT(diffRepository()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

    action = new QAction(tr("Log"), this);
    m_repositoryActionList.append(action);
Eike Ziller's avatar
Eike Ziller committed
354
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::LOGMULTI), context);
cerf's avatar
cerf committed
355 356 357 358 359 360
    connect(action, SIGNAL(triggered()), this, SLOT(logRepository()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

    action = new QAction(tr("Revert..."), this);
    m_repositoryActionList.append(action);
Eike Ziller's avatar
Eike Ziller committed
361
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::REVERTMULTI), context);
cerf's avatar
cerf committed
362 363 364 365 366 367
    connect(action, SIGNAL(triggered()), this, SLOT(revertAll()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

    action = new QAction(tr("Status"), this);
    m_repositoryActionList.append(action);
Eike Ziller's avatar
Eike Ziller committed
368
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::STATUSMULTI), context);
cerf's avatar
cerf committed
369 370 371 372 373 374 375 376
    connect(action, SIGNAL(triggered()), this, SLOT(statusMulti()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);
}


void BazaarPlugin::diffRepository()
{
hjk's avatar
hjk committed
377
    const VcsBase::VcsBasePluginState state = currentState();
Tobias Hunger's avatar
Tobias Hunger committed
378 379
    QTC_ASSERT(state.hasTopLevel(), return);
    m_client->diff(state.topLevel());
cerf's avatar
cerf committed
380 381 382 383
}

void BazaarPlugin::logRepository()
{
hjk's avatar
hjk committed
384
    const VcsBase::VcsBasePluginState state = currentState();
Tobias Hunger's avatar
Tobias Hunger committed
385
    QTC_ASSERT(state.hasTopLevel(), return);
386
    QStringList extraOptions;
387
    extraOptions += QLatin1String("--limit=") + QString::number(settings().intValue(BazaarSettings::logCountKey));
388
    m_client->log(state.topLevel(), QStringList(), extraOptions);
cerf's avatar
cerf committed
389 390 391 392
}

void BazaarPlugin::revertAll()
{
hjk's avatar
hjk committed
393
    const VcsBase::VcsBasePluginState state = currentState();
cerf's avatar
cerf committed
394 395 396 397 398 399 400 401 402 403 404 405
    QTC_ASSERT(state.hasTopLevel(), return);

    QDialog dialog;
    Ui::RevertDialog revertUi;
    revertUi.setupUi(&dialog);
    if (dialog.exec() != QDialog::Accepted)
        return;
    m_client->revertAll(state.topLevel(), revertUi.revisionLineEdit->text());
}

void BazaarPlugin::statusMulti()
{
hjk's avatar
hjk committed
406
    const VcsBase::VcsBasePluginState state = currentState();
cerf's avatar
cerf committed
407 408 409 410 411 412 413 414 415 416 417
    QTC_ASSERT(state.hasTopLevel(), return);
    m_client->status(state.topLevel());
}

void BazaarPlugin::createRepositoryActions(const Core::Context &context)
{
    QAction *action = 0;
    Core::Command *command = 0;

    action = new QAction(tr("Pull..."), this);
    m_repositoryActionList.append(action);
Eike Ziller's avatar
Eike Ziller committed
418
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::PULL), context);
cerf's avatar
cerf committed
419 420 421 422 423 424
    connect(action, SIGNAL(triggered()), this, SLOT(pull()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

    action = new QAction(tr("Push..."), this);
    m_repositoryActionList.append(action);
Eike Ziller's avatar
Eike Ziller committed
425
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::PUSH), context);
cerf's avatar
cerf committed
426 427 428 429 430 431
    connect(action, SIGNAL(triggered()), this, SLOT(push()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

    action = new QAction(tr("Update..."), this);
    m_repositoryActionList.append(action);
Eike Ziller's avatar
Eike Ziller committed
432
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::UPDATE), context);
cerf's avatar
cerf committed
433 434 435 436 437 438
    connect(action, SIGNAL(triggered()), this, SLOT(update()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

    action = new QAction(tr("Commit..."), this);
    m_repositoryActionList.append(action);
Eike Ziller's avatar
Eike Ziller committed
439
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::COMMIT), context);
440
    command->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+Z,Meta+C") : tr("ALT+Z,Alt+C")));
cerf's avatar
cerf committed
441 442 443 444
    connect(action, SIGNAL(triggered()), this, SLOT(commit()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

cerf's avatar
cerf committed
445
    QAction *createRepositoryAction = new QAction(tr("Create Repository..."), this);
Eike Ziller's avatar
Eike Ziller committed
446
    command = Core::ActionManager::registerAction(createRepositoryAction, Core::Id(Constants::CREATE_REPOSITORY), context);
cerf's avatar
cerf committed
447 448 449 450 451 452
    connect(createRepositoryAction, SIGNAL(triggered()), this, SLOT(createRepository()));
    m_bazaarContainer->addAction(command);
}

void BazaarPlugin::pull()
{
hjk's avatar
hjk committed
453
    const VcsBase::VcsBasePluginState state = currentState();
cerf's avatar
cerf committed
454 455 456 457 458
    QTC_ASSERT(state.hasTopLevel(), return);

    PullOrPushDialog dialog(PullOrPushDialog::PullMode);
    if (dialog.exec() != QDialog::Accepted)
        return;
459 460 461 462 463 464 465 466 467
    QStringList extraOptions;
    if (dialog.isRememberOptionEnabled())
        extraOptions += QLatin1String("--remember");
    if (dialog.isOverwriteOptionEnabled())
        extraOptions += QLatin1String("--overwrite");
    if (dialog.isLocalOptionEnabled())
        extraOptions += QLatin1String("--local");
    if (!dialog.revision().isEmpty())
        extraOptions << QLatin1String("-r") << dialog.revision();
cerf's avatar
cerf committed
468 469 470 471 472
    m_client->synchronousPull(state.topLevel(), dialog.branchLocation(), extraOptions);
}

void BazaarPlugin::push()
{
hjk's avatar
hjk committed
473
    const VcsBase::VcsBasePluginState state = currentState();
cerf's avatar
cerf committed
474 475 476 477 478
    QTC_ASSERT(state.hasTopLevel(), return);

    PullOrPushDialog dialog(PullOrPushDialog::PushMode);
    if (dialog.exec() != QDialog::Accepted)
        return;
479 480 481 482 483 484 485 486 487 488 489
    QStringList extraOptions;
    if (dialog.isRememberOptionEnabled())
        extraOptions += QLatin1String("--remember");
    if (dialog.isOverwriteOptionEnabled())
        extraOptions += QLatin1String("--overwrite");
    if (dialog.isUseExistingDirectoryOptionEnabled())
        extraOptions += QLatin1String("--use-existing-dir");
    if (dialog.isCreatePrefixOptionEnabled())
        extraOptions += QLatin1String("--create-prefix");
    if (!dialog.revision().isEmpty())
        extraOptions << QLatin1String("-r") << dialog.revision();
cerf's avatar
cerf committed
490 491 492 493 494
    m_client->synchronousPush(state.topLevel(), dialog.branchLocation(), extraOptions);
}

void BazaarPlugin::update()
{
hjk's avatar
hjk committed
495
    const VcsBase::VcsBasePluginState state = currentState();
cerf's avatar
cerf committed
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
    QTC_ASSERT(state.hasTopLevel(), return);

    QDialog dialog;
    Ui::RevertDialog revertUi;
    revertUi.setupUi(&dialog);
    dialog.setWindowTitle(tr("Update"));
    if (dialog.exec() != QDialog::Accepted)
        return;
    m_client->update(state.topLevel(), revertUi.revisionLineEdit->text());
}

void BazaarPlugin::createSubmitEditorActions()
{
    Core::Context context(Constants::COMMIT_ID);
    Core::Command *command;

hjk's avatar
hjk committed
512
    m_editorCommit = new QAction(VcsBase::VcsBaseSubmitEditor::submitIcon(), tr("Commit"), this);
Eike Ziller's avatar
Eike Ziller committed
513
    command = Core::ActionManager::registerAction(m_editorCommit, Core::Id(Constants::COMMIT), context);
cerf's avatar
cerf committed
514 515 516
    command->setAttribute(Core::Command::CA_UpdateText);
    connect(m_editorCommit, SIGNAL(triggered()), this, SLOT(commitFromEditor()));

hjk's avatar
hjk committed
517
    m_editorDiff = new QAction(VcsBase::VcsBaseSubmitEditor::diffIcon(), tr("Diff &Selected Files"), this);
Eike Ziller's avatar
Eike Ziller committed
518
    command = Core::ActionManager::registerAction(m_editorDiff, Core::Id(Constants::DIFFEDITOR), context);
cerf's avatar
cerf committed
519 520

    m_editorUndo = new QAction(tr("&Undo"), this);
Eike Ziller's avatar
Eike Ziller committed
521
    command = Core::ActionManager::registerAction(m_editorUndo, Core::Id(Core::Constants::UNDO), context);
cerf's avatar
cerf committed
522 523

    m_editorRedo = new QAction(tr("&Redo"), this);
Eike Ziller's avatar
Eike Ziller committed
524
    command = Core::ActionManager::registerAction(m_editorRedo, Core::Id(Core::Constants::REDO), context);
cerf's avatar
cerf committed
525 526 527 528
}

void BazaarPlugin::commit()
{
hjk's avatar
hjk committed
529
    if (VcsBase::VcsBaseSubmitEditor::raiseSubmitEditor())
cerf's avatar
cerf committed
530 531
        return;

hjk's avatar
hjk committed
532
    const VcsBase::VcsBasePluginState state = currentState();
cerf's avatar
cerf committed
533 534 535 536
    QTC_ASSERT(state.hasTopLevel(), return);

    m_submitRepository = state.topLevel();

hjk's avatar
hjk committed
537 538
    connect(m_client, SIGNAL(parsedStatus(QList<VcsBase::VcsBaseClient::StatusItem>)),
            this, SLOT(showCommitWidget(QList<VcsBase::VcsBaseClient::StatusItem>)));
539 540
    // The "--short" option allows to easily parse status output
    m_client->emitParsedStatus(m_submitRepository, QStringList(QLatin1String("--short")));
cerf's avatar
cerf committed
541 542
}

hjk's avatar
hjk committed
543
void BazaarPlugin::showCommitWidget(const QList<VcsBase::VcsBaseClient::StatusItem> &status)
cerf's avatar
cerf committed
544
{
hjk's avatar
hjk committed
545
    VcsBase::VcsBaseOutputWindow *outputWindow = VcsBase::VcsBaseOutputWindow::instance();
cerf's avatar
cerf committed
546
    //Once we receive our data release the connection so it can be reused elsewhere
hjk's avatar
hjk committed
547 548
    disconnect(m_client, SIGNAL(parsedStatus(QList<VcsBase::VcsBaseClient::StatusItem>)),
               this, SLOT(showCommitWidget(QList<VcsBase::VcsBaseClient::StatusItem>)));
cerf's avatar
cerf committed
549 550 551 552 553 554 555 556 557

    if (status.isEmpty()) {
        outputWindow->appendError(tr("There are no changes to commit."));
        return;
    }

    deleteCommitLog();

    // Open commit log
558 559 560 561 562
    QString changeLogPattern = QDir::tempPath();
    if (!changeLogPattern.endsWith(QLatin1Char('/')))
        changeLogPattern += QLatin1Char('/');
    changeLogPattern += QLatin1String("qtcreator-bzr-XXXXXX.msg");
    m_changeLog = new QTemporaryFile(changeLogPattern, this);
cerf's avatar
cerf committed
563 564 565 566 567
    if (!m_changeLog->open()) {
        outputWindow->appendError(tr("Unable to generate a temporary file for the commit editor."));
        return;
    }

hjk's avatar
hjk committed
568 569 570
    Core::IEditor *editor = Core::EditorManager::openEditor(m_changeLog->fileName(),
                                                            Constants::COMMIT_ID,
                                                            Core::EditorManager::ModeSwitch);
cerf's avatar
cerf committed
571 572 573 574 575 576 577 578 579 580 581 582
    if (!editor) {
        outputWindow->appendError(tr("Unable to create an editor for the commit."));
        return;
    }

    CommitEditor *commitEditor = qobject_cast<CommitEditor *>(editor);

    if (!commitEditor) {
        outputWindow->appendError(tr("Unable to create a commit editor."));
        return;
    }

583 584 585 586 587
    commitEditor->registerActions(m_editorUndo, m_editorRedo, m_editorCommit, m_editorDiff);
    connect(commitEditor, SIGNAL(diffSelectedFiles(QStringList)),
            this, SLOT(diffFromEditorSelected(QStringList)));
    commitEditor->setCheckScriptWorkingDirectory(m_submitRepository);

cerf's avatar
cerf committed
588 589 590 591 592
    const QString msg = tr("Commit changes for \"%1\".").
            arg(QDir::toNativeSeparators(m_submitRepository));
    commitEditor->setDisplayName(msg);

    const BranchInfo branch = m_client->synchronousBranchQuery(m_submitRepository);
593 594
    commitEditor->setFields(m_submitRepository, branch,
                            m_bazaarSettings.stringValue(BazaarSettings::userNameKey),
595
                            m_bazaarSettings.stringValue(BazaarSettings::userEmailKey), status);
cerf's avatar
cerf committed
596 597 598 599 600 601 602 603 604 605 606 607 608
}

void BazaarPlugin::diffFromEditorSelected(const QStringList &files)
{
    m_client->diff(m_submitRepository, files);
}

void BazaarPlugin::commitFromEditor()
{
    if (!m_changeLog)
        return;

    //use the same functionality than if the user closes the file without completing the commit
hjk's avatar
hjk committed
609
    Core::ICore::editorManager()->closeEditors(Core::ICore::editorManager()->editorsForFileName(m_changeLog->fileName()));
cerf's avatar
cerf committed
610 611
}

hjk's avatar
hjk committed
612
bool BazaarPlugin::submitEditorAboutToClose(VcsBase::VcsBaseSubmitEditor *submitEditor)
cerf's avatar
cerf committed
613 614 615
{
    if (!m_changeLog)
        return true;
616
    Core::IDocument *editorDocument = submitEditor->document();
cerf's avatar
cerf committed
617
    const CommitEditor *commitEditor = qobject_cast<const CommitEditor *>(submitEditor);
618
    if (!editorDocument || !commitEditor)
cerf's avatar
cerf committed
619 620
        return true;

621
    bool dummyPrompt = m_bazaarSettings.boolValue(BazaarSettings::promptOnSubmitKey);
hjk's avatar
hjk committed
622
    const VcsBase::VcsBaseSubmitEditor::PromptSubmitResult response =
cerf's avatar
cerf committed
623 624
            commitEditor->promptSubmit(tr("Close Commit Editor"), tr("Do you want to commit the changes?"),
                                       tr("Message check failed. Do you want to proceed?"),
625
                                       &dummyPrompt, dummyPrompt);
cerf's avatar
cerf committed
626 627

    switch (response) {
hjk's avatar
hjk committed
628
    case VcsBase::VcsBaseSubmitEditor::SubmitCanceled:
cerf's avatar
cerf committed
629
        return false;
hjk's avatar
hjk committed
630
    case VcsBase::VcsBaseSubmitEditor::SubmitDiscarded:
cerf's avatar
cerf committed
631 632 633 634 635 636
        deleteCommitLog();
        return true;
    default:
        break;
    }

637
    QStringList files = commitEditor->checkedFiles();
cerf's avatar
cerf committed
638 639
    if (!files.empty()) {
        //save the commit message
640
        if (!Core::DocumentManager::saveDocument(editorDocument))
641
            return false;
cerf's avatar
cerf committed
642

643 644 645
        //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) {
646
            const QStringList parts = iFile->split(QLatin1String(" => "), QString::SkipEmptyParts);
647 648 649 650
            if (!parts.isEmpty())
                *iFile = parts.last();
        }

cerf's avatar
cerf committed
651
        const BazaarCommitWidget *commitWidget = commitEditor->commitWidget();
652 653 654 655 656 657 658 659 660 661 662 663
        QStringList extraOptions;
        // Author
        if (!commitWidget->committer().isEmpty())
            extraOptions.append(QLatin1String("--author=") + commitWidget->committer());
        // Fixed bugs
        foreach (const QString &fix, commitWidget->fixedBugs()) {
            if (!fix.isEmpty())
                extraOptions << QLatin1String("--fixes") << fix;
        }
        // Whether local commit or not
        if (commitWidget->isLocalOptionEnabled())
            extraOptions += QLatin1String("--local");
664
        m_client->commit(m_submitRepository, files, editorDocument->fileName(), extraOptions);
cerf's avatar
cerf committed
665 666 667 668 669 670 671 672 673 674 675 676
    }
    return true;
}

void BazaarPlugin::deleteCommitLog()
{
    if (m_changeLog) {
        delete m_changeLog;
        m_changeLog = 0;
    }
}

hjk's avatar
hjk committed
677
void BazaarPlugin::updateActions(VcsBase::VcsBasePlugin::ActionState as)
cerf's avatar
cerf committed
678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699
{
    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);

    foreach (QAction *repoAction, m_repositoryActionList)
        repoAction->setEnabled(repoEnabled);
}

Q_EXPORT_PLUGIN(BazaarPlugin)