bazaarplugin.cpp 25.3 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
#include <QtGlobal>
#include <QDir>
#include <QDialog>
#include <QFileDialog>
cerf's avatar
cerf committed
74 75 76 77

using namespace Bazaar::Internal;
using namespace Bazaar;

hjk's avatar
hjk committed
78
static const VcsBase::VcsBaseEditorParameters editorParameters[] = {
cerf's avatar
cerf committed
79
    {
hjk's avatar
hjk committed
80
        VcsBase::RegularCommandOutput, //type
cerf's avatar
cerf committed
81 82 83 84 85 86
        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
87
    {   VcsBase::LogOutput,
cerf's avatar
cerf committed
88 89 90 91 92 93
        Constants::FILELOG_ID,
        Constants::FILELOG_DISPLAY_NAME,
        Constants::FILELOG,
        Constants::LOGAPP,
        Constants::LOGEXT},

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

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

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


BazaarPlugin *BazaarPlugin::m_instance = 0;

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

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

    m_instance = 0;
}

142
bool BazaarPlugin::initialize(const QStringList &arguments, QString *errorMessage)
cerf's avatar
cerf committed
143
{
144 145 146
    Q_UNUSED(arguments);
    Q_UNUSED(errorMessage);

hjk's avatar
hjk committed
147
    typedef VcsBase::VcsEditorFactory<BazaarEditor> BazaarEditorFactory;
cerf's avatar
cerf committed
148

149
    m_client = new BazaarClient(&m_bazaarSettings);
150
    initializeVcs(new BazaarControl(m_client));
cerf's avatar
cerf committed
151 152 153

    m_optionsPage = new OptionsPage();
    addAutoReleasedObject(m_optionsPage);
hjk's avatar
hjk committed
154
    m_bazaarSettings.readSettings(Core::ICore::settings());
cerf's avatar
cerf committed
155 156 157 158

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

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

hjk's avatar
hjk committed
163
    addAutoReleasedObject(new VcsBase::VcsSubmitEditorFactory<CommitEditor>(&submitEditorParameters));
cerf's avatar
cerf committed
164 165 166 167 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

    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
196 197 198 199
        const bool userIdChanged = !m_bazaarSettings.sameUserId(settings);
        m_bazaarSettings = settings;
        if (userIdChanged)
            client()->synchronousSetUserId();
200
        static_cast<BazaarControl *>(versionControl())->emitConfigurationChanged();
cerf's avatar
cerf committed
201 202 203 204 205 206 207 208
    }
}

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

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

    createFileActions(context);
214
    m_bazaarContainer->addSeparator(context);
cerf's avatar
cerf committed
215
    createDirectoryActions(context);
216
    m_bazaarContainer->addSeparator(context);
cerf's avatar
cerf committed
217
    createRepositoryActions(context);
218
    m_bazaarContainer->addSeparator(context);
cerf's avatar
cerf committed
219 220

    // Request the Tools menu and add the Bazaar menu to it
Eike Ziller's avatar
Eike Ziller committed
221
    Core::ActionContainer *toolsMenu = Core::ActionManager::actionContainer(Core::Id(Core::Constants::M_TOOLS));
cerf's avatar
cerf committed
222 223 224 225 226 227 228 229 230
    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
231
    command = Core::ActionManager::registerAction(m_annotateFile, Core::Id(Constants::ANNOTATE), context);
cerf's avatar
cerf committed
232 233 234 235 236 237
    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
238
    command = Core::ActionManager::registerAction(m_diffFile, Core::Id(Constants::DIFF), context);
cerf's avatar
cerf committed
239
    command->setAttribute(Core::Command::CA_UpdateText);
240
    command->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+Z,Meta+D") : tr("ALT+Z,Alt+D")));
cerf's avatar
cerf committed
241 242 243 244 245
    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
246
    command = Core::ActionManager::registerAction(m_logFile, Core::Id(Constants::LOG), context);
cerf's avatar
cerf committed
247
    command->setAttribute(Core::Command::CA_UpdateText);
248
    command->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+Z,Meta+L") : tr("ALT+Z,Alt+L")));
cerf's avatar
cerf committed
249 250 251 252 253
    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
254
    command = Core::ActionManager::registerAction(m_statusFile, Core::Id(Constants::STATUS), context);
cerf's avatar
cerf committed
255
    command->setAttribute(Core::Command::CA_UpdateText);
256
    command->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+Z,Meta+S") : tr("ALT+Z,Alt+S")));
cerf's avatar
cerf committed
257 258 259 260
    connect(m_statusFile, SIGNAL(triggered()), this, SLOT(statusCurrentFile()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

261
    m_bazaarContainer->addSeparator(context);
cerf's avatar
cerf committed
262 263

    m_addAction = new Utils::ParameterAction(tr("Add"), tr("Add \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
Eike Ziller's avatar
Eike Ziller committed
264
    command = Core::ActionManager::registerAction(m_addAction, Core::Id(Constants::ADD), context);
cerf's avatar
cerf committed
265 266 267 268 269 270
    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
271
    command = Core::ActionManager::registerAction(m_deleteAction, Core::Id(Constants::DELETE), context);
cerf's avatar
cerf committed
272 273 274 275 276 277
    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
278
    command = Core::ActionManager::registerAction(m_revertFile, Core::Id(Constants::REVERT), context);
cerf's avatar
cerf committed
279 280 281 282 283 284 285 286
    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
287
    const VcsBase::VcsBasePluginState state = currentState();
Tobias Hunger's avatar
Tobias Hunger committed
288 289
    QTC_ASSERT(state.hasFile(), return);
    m_client->synchronousAdd(state.currentFileTopLevel(), state.relativeCurrentFile());
cerf's avatar
cerf committed
290 291 292 293
}

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

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

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

void BazaarPlugin::revertCurrentFile()
{
hjk's avatar
hjk committed
316
    const VcsBase::VcsBasePluginState state = currentState();
cerf's avatar
cerf committed
317 318 319 320 321 322 323 324 325 326 327 328 329 330
    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
331
    const VcsBase::VcsBasePluginState state = currentState();
Tobias Hunger's avatar
Tobias Hunger committed
332 333
    QTC_ASSERT(state.hasFile(), return);
    m_client->status(state.currentFileTopLevel(), state.relativeCurrentFile());
cerf's avatar
cerf committed
334 335 336 337 338 339 340 341 342
}

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
343
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::DIFFMULTI), context);
cerf's avatar
cerf committed
344 345 346 347 348 349
    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
350
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::LOGMULTI), context);
cerf's avatar
cerf committed
351 352 353 354 355 356
    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
357
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::REVERTMULTI), context);
cerf's avatar
cerf committed
358 359 360 361 362 363
    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
364
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::STATUSMULTI), context);
cerf's avatar
cerf committed
365 366 367 368 369 370 371 372
    connect(action, SIGNAL(triggered()), this, SLOT(statusMulti()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);
}


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

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

void BazaarPlugin::revertAll()
{
hjk's avatar
hjk committed
389
    const VcsBase::VcsBasePluginState state = currentState();
cerf's avatar
cerf committed
390 391 392 393 394 395 396 397 398 399 400 401
    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
402
    const VcsBase::VcsBasePluginState state = currentState();
cerf's avatar
cerf committed
403 404 405 406 407 408 409 410 411 412 413
    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
414
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::PULL), context);
cerf's avatar
cerf committed
415 416 417 418 419 420
    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
421
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::PUSH), context);
cerf's avatar
cerf committed
422 423 424 425 426 427
    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
428
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::UPDATE), context);
cerf's avatar
cerf committed
429 430 431 432 433 434
    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
435
    command = Core::ActionManager::registerAction(action, Core::Id(Constants::COMMIT), context);
436
    command->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+Z,Meta+C") : tr("ALT+Z,Alt+C")));
cerf's avatar
cerf committed
437 438 439 440
    connect(action, SIGNAL(triggered()), this, SLOT(commit()));
    m_bazaarContainer->addAction(command);
    m_commandLocator->appendCommand(command);

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

void BazaarPlugin::pull()
{
hjk's avatar
hjk committed
449
    const VcsBase::VcsBasePluginState state = currentState();
cerf's avatar
cerf committed
450 451 452 453 454
    QTC_ASSERT(state.hasTopLevel(), return);

    PullOrPushDialog dialog(PullOrPushDialog::PullMode);
    if (dialog.exec() != QDialog::Accepted)
        return;
455 456 457 458 459 460 461 462 463
    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
464 465 466 467 468
    m_client->synchronousPull(state.topLevel(), dialog.branchLocation(), extraOptions);
}

void BazaarPlugin::push()
{
hjk's avatar
hjk committed
469
    const VcsBase::VcsBasePluginState state = currentState();
cerf's avatar
cerf committed
470 471 472 473 474
    QTC_ASSERT(state.hasTopLevel(), return);

    PullOrPushDialog dialog(PullOrPushDialog::PushMode);
    if (dialog.exec() != QDialog::Accepted)
        return;
475 476 477 478 479 480 481 482 483 484 485
    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
486 487 488 489 490
    m_client->synchronousPush(state.topLevel(), dialog.branchLocation(), extraOptions);
}

void BazaarPlugin::update()
{
hjk's avatar
hjk committed
491
    const VcsBase::VcsBasePluginState state = currentState();
cerf's avatar
cerf committed
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
    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
508
    m_editorCommit = new QAction(VcsBase::VcsBaseSubmitEditor::submitIcon(), tr("Commit"), this);
Eike Ziller's avatar
Eike Ziller committed
509
    command = Core::ActionManager::registerAction(m_editorCommit, Core::Id(Constants::COMMIT), context);
cerf's avatar
cerf committed
510 511 512
    command->setAttribute(Core::Command::CA_UpdateText);
    connect(m_editorCommit, SIGNAL(triggered()), this, SLOT(commitFromEditor()));

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

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

    m_editorRedo = new QAction(tr("&Redo"), this);
Eike Ziller's avatar
Eike Ziller committed
520
    command = Core::ActionManager::registerAction(m_editorRedo, Core::Id(Core::Constants::REDO), context);
cerf's avatar
cerf committed
521 522 523 524
}

void BazaarPlugin::commit()
{
hjk's avatar
hjk committed
525
    if (VcsBase::VcsBaseSubmitEditor::raiseSubmitEditor())
cerf's avatar
cerf committed
526 527
        return;

hjk's avatar
hjk committed
528
    const VcsBase::VcsBasePluginState state = currentState();
cerf's avatar
cerf committed
529 530 531 532
    QTC_ASSERT(state.hasTopLevel(), return);

    m_submitRepository = state.topLevel();

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

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

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

551 552 553 554 555 556
    // Start new temp file
    Utils::TempFileSaver saver;
    // Keep the file alive, else it removes self and forgets its name
    saver.setAutoRemove(false);
    if (!saver.finalize()) {
        VcsBase::VcsBaseOutputWindow::instance()->append(saver.errorString());
cerf's avatar
cerf committed
557 558 559
        return;
    }

560
    Core::IEditor *editor = Core::EditorManager::openEditor(saver.fileName(),
hjk's avatar
hjk committed
561 562
                                                            Constants::COMMIT_ID,
                                                            Core::EditorManager::ModeSwitch);
cerf's avatar
cerf committed
563 564 565 566 567 568 569 570 571 572 573 574
    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;
    }

575 576 577 578 579
    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
580 581 582 583 584
    const QString msg = tr("Commit changes for \"%1\".").
            arg(QDir::toNativeSeparators(m_submitRepository));
    commitEditor->setDisplayName(msg);

    const BranchInfo branch = m_client->synchronousBranchQuery(m_submitRepository);
585 586
    commitEditor->setFields(m_submitRepository, branch,
                            m_bazaarSettings.stringValue(BazaarSettings::userNameKey),
587
                            m_bazaarSettings.stringValue(BazaarSettings::userEmailKey), status);
cerf's avatar
cerf committed
588 589 590 591 592 593 594 595 596
}

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

void BazaarPlugin::commitFromEditor()
{
597 598 599
    // Close the submit editor
    m_submitActionTriggered = true;
    Core::ICore::editorManager()->closeEditor();
cerf's avatar
cerf committed
600 601
}

hjk's avatar
hjk committed
602
bool BazaarPlugin::submitEditorAboutToClose(VcsBase::VcsBaseSubmitEditor *submitEditor)
cerf's avatar
cerf committed
603
{
604
    Core::IDocument *editorDocument = submitEditor->document();
cerf's avatar
cerf committed
605
    const CommitEditor *commitEditor = qobject_cast<const CommitEditor *>(submitEditor);
606
    if (!editorDocument || !commitEditor)
cerf's avatar
cerf committed
607 608
        return true;

609
    bool dummyPrompt = m_bazaarSettings.boolValue(BazaarSettings::promptOnSubmitKey);
hjk's avatar
hjk committed
610
    const VcsBase::VcsBaseSubmitEditor::PromptSubmitResult response =
cerf's avatar
cerf committed
611 612
            commitEditor->promptSubmit(tr("Close Commit Editor"), tr("Do you want to commit the changes?"),
                                       tr("Message check failed. Do you want to proceed?"),
613 614
                                       &dummyPrompt, !m_submitActionTriggered);
    m_submitActionTriggered = false;
cerf's avatar
cerf committed
615 616

    switch (response) {
hjk's avatar
hjk committed
617
    case VcsBase::VcsBaseSubmitEditor::SubmitCanceled:
cerf's avatar
cerf committed
618
        return false;
hjk's avatar
hjk committed
619
    case VcsBase::VcsBaseSubmitEditor::SubmitDiscarded:
cerf's avatar
cerf committed
620 621 622 623 624
        return true;
    default:
        break;
    }

625
    QStringList files = commitEditor->checkedFiles();
cerf's avatar
cerf committed
626 627
    if (!files.empty()) {
        //save the commit message
628
        if (!Core::DocumentManager::saveDocument(editorDocument))
629
            return false;
cerf's avatar
cerf committed
630

631 632 633
        //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) {
634
            const QStringList parts = iFile->split(QLatin1String(" => "), QString::SkipEmptyParts);
635 636 637 638
            if (!parts.isEmpty())
                *iFile = parts.last();
        }

cerf's avatar
cerf committed
639
        const BazaarCommitWidget *commitWidget = commitEditor->commitWidget();
640 641 642 643 644 645 646 647 648 649 650 651
        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");
652
        m_client->commit(m_submitRepository, files, editorDocument->fileName(), extraOptions);
cerf's avatar
cerf committed
653 654 655 656
    }
    return true;
}

hjk's avatar
hjk committed
657
void BazaarPlugin::updateActions(VcsBase::VcsBasePlugin::ActionState as)
cerf's avatar
cerf committed
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679
{
    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)