mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-29 07:24:13 +01:00
Removing some unused files.
git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@210 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
parent
557f33fe49
commit
d09d755253
@ -1,134 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "editmode.h"
|
||||
#include "editormanager.h"
|
||||
#include "coreconstants.h"
|
||||
#include "modemanager.h"
|
||||
#include "uniqueidmanager.h"
|
||||
#include "minisplitter.h"
|
||||
#include "findplaceholder.h"
|
||||
#include "outputpane.h"
|
||||
#include "navigationwidget.h"
|
||||
#include "rightpane.h"
|
||||
#include "ieditor.h"
|
||||
#include "ifile.h"
|
||||
|
||||
#include <QtCore/QLatin1String>
|
||||
#include <QtGui/QHBoxLayout>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QSplitter>
|
||||
|
||||
using namespace Core;
|
||||
using namespace Core::Internal;
|
||||
|
||||
EditMode::EditMode(EditorManager *editorManager) :
|
||||
m_editorManager(editorManager),
|
||||
m_splitter(new MiniSplitter),
|
||||
m_rightSplitWidgetLayout(new QVBoxLayout)
|
||||
{
|
||||
m_rightSplitWidgetLayout->setSpacing(0);
|
||||
m_rightSplitWidgetLayout->setMargin(0);
|
||||
QWidget *rightSplitWidget = new QWidget;
|
||||
rightSplitWidget->setLayout(m_rightSplitWidgetLayout);
|
||||
m_rightSplitWidgetLayout->insertWidget(0, new Core::EditorManagerPlaceHolder(this));
|
||||
|
||||
MiniSplitter *rightPaneSplitter = new MiniSplitter;
|
||||
rightPaneSplitter->insertWidget(0, rightSplitWidget);
|
||||
rightPaneSplitter->insertWidget(1, new RightPanePlaceHolder(this));
|
||||
rightPaneSplitter->setStretchFactor(0, 1);
|
||||
rightPaneSplitter->setStretchFactor(1, 0);
|
||||
|
||||
MiniSplitter *splitter = new MiniSplitter;
|
||||
splitter->setOrientation(Qt::Vertical);
|
||||
splitter->insertWidget(0, rightPaneSplitter);
|
||||
splitter->insertWidget(1, new Core::OutputPanePlaceHolder(this));
|
||||
splitter->setStretchFactor(0, 3);
|
||||
splitter->setStretchFactor(1, 0);
|
||||
|
||||
m_splitter->insertWidget(0, new NavigationWidgetPlaceHolder(this));
|
||||
m_splitter->insertWidget(1, splitter);
|
||||
m_splitter->setStretchFactor(0, 0);
|
||||
m_splitter->setStretchFactor(1, 1);
|
||||
|
||||
ModeManager *modeManager = ModeManager::instance();
|
||||
connect(modeManager, SIGNAL(currentModeChanged(Core::IMode*)),
|
||||
this, SLOT(grabEditorManager(Core::IMode*)));
|
||||
m_splitter->setFocusProxy(m_editorManager);
|
||||
}
|
||||
|
||||
EditMode::~EditMode()
|
||||
{
|
||||
// Make sure the editor manager does not get deleted
|
||||
m_editorManager->setParent(0);
|
||||
delete m_splitter;
|
||||
}
|
||||
|
||||
QString EditMode::name() const
|
||||
{
|
||||
return tr("Edit");
|
||||
}
|
||||
|
||||
QIcon EditMode::icon() const
|
||||
{
|
||||
return QIcon(QLatin1String(":/fancyactionbar/images/mode_Edit.png"));
|
||||
}
|
||||
|
||||
int EditMode::priority() const
|
||||
{
|
||||
return Constants::P_MODE_EDIT;
|
||||
}
|
||||
|
||||
QWidget* EditMode::widget()
|
||||
{
|
||||
return m_splitter;
|
||||
}
|
||||
|
||||
const char* EditMode::uniqueModeName() const
|
||||
{
|
||||
return Constants::MODE_EDIT;
|
||||
}
|
||||
|
||||
QList<int> EditMode::context() const
|
||||
{
|
||||
static QList<int> contexts = QList<int>() <<
|
||||
UniqueIDManager::instance()->uniqueIdentifier(Constants::C_EDIT_MODE) <<
|
||||
UniqueIDManager::instance()->uniqueIdentifier(Constants::C_EDITORMANAGER) <<
|
||||
UniqueIDManager::instance()->uniqueIdentifier(Constants::C_NAVIGATION_PANE);
|
||||
return contexts;
|
||||
}
|
||||
|
||||
void EditMode::grabEditorManager(Core::IMode *mode)
|
||||
{
|
||||
if (mode != this)
|
||||
return;
|
||||
|
||||
if (m_editorManager->currentEditor())
|
||||
m_editorManager->currentEditor()->widget()->setFocus();
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef EDITMODE_H
|
||||
#define EDITMODE_H
|
||||
|
||||
#include <coreplugin/imode.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QSplitter;
|
||||
class QWidget;
|
||||
class QVBoxLayout;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
|
||||
class EditorManager;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class EditMode : public Core::IMode
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EditMode(EditorManager *editorManager);
|
||||
~EditMode();
|
||||
|
||||
// IMode
|
||||
QString name() const;
|
||||
QIcon icon() const;
|
||||
int priority() const;
|
||||
QWidget* widget();
|
||||
const char* uniqueModeName() const;
|
||||
QList<int> context() const;
|
||||
|
||||
private slots:
|
||||
void grabEditorManager(Core::IMode *mode);
|
||||
|
||||
private:
|
||||
EditorManager *m_editorManager;
|
||||
QSplitter *m_splitter;
|
||||
QVBoxLayout *m_rightSplitWidgetLayout;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
#endif // EDITMODE_H
|
@ -1,1937 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "editormanager.h"
|
||||
#include "editorview.h"
|
||||
#include "openeditorswindow.h"
|
||||
#include "openeditorsview.h"
|
||||
#include "openeditorsmodel.h"
|
||||
#include "openwithdialog.h"
|
||||
#include "filemanager.h"
|
||||
#include "icore.h"
|
||||
#include "iversioncontrol.h"
|
||||
#include "mimedatabase.h"
|
||||
#include "tabpositionindicator.h"
|
||||
#include "vcsmanager.h"
|
||||
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/modemanager.h>
|
||||
#include <coreplugin/uniqueidmanager.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/editormanager/ieditorfactory.h>
|
||||
#include <coreplugin/editormanager/iexternaleditor.h>
|
||||
#include <coreplugin/baseview.h>
|
||||
#include <coreplugin/imode.h>
|
||||
#include <coreplugin/settingsdatabase.h>
|
||||
#include <coreplugin/variablemanager.h>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <utils/consoleprocess.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/QSet>
|
||||
#include <QtCore/QSettings>
|
||||
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QFileDialog>
|
||||
#include <QtGui/QLayout>
|
||||
#include <QtGui/QMainWindow>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtGui/QSplitter>
|
||||
#include <QtGui/QStackedLayout>
|
||||
|
||||
Q_DECLARE_METATYPE(Core::IEditor*)
|
||||
|
||||
using namespace Core;
|
||||
using namespace Core::Internal;
|
||||
using namespace Utils;
|
||||
|
||||
enum { debugEditorManager=0 };
|
||||
|
||||
static inline ExtensionSystem::PluginManager *pluginManager()
|
||||
{
|
||||
return ExtensionSystem::PluginManager::instance();
|
||||
}
|
||||
|
||||
//===================EditorManager=====================
|
||||
|
||||
EditorManagerPlaceHolder *EditorManagerPlaceHolder::m_current = 0;
|
||||
|
||||
EditorManagerPlaceHolder::EditorManagerPlaceHolder(Core::IMode *mode, QWidget *parent)
|
||||
: QWidget(parent), m_mode(mode)
|
||||
{
|
||||
setLayout(new QVBoxLayout);
|
||||
layout()->setMargin(0);
|
||||
connect(Core::ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode *)),
|
||||
this, SLOT(currentModeChanged(Core::IMode *)));
|
||||
|
||||
currentModeChanged(Core::ModeManager::instance()->currentMode());
|
||||
}
|
||||
|
||||
EditorManagerPlaceHolder::~EditorManagerPlaceHolder()
|
||||
{
|
||||
if (m_current == this) {
|
||||
EditorManager::instance()->setParent(0);
|
||||
EditorManager::instance()->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorManagerPlaceHolder::currentModeChanged(Core::IMode *mode)
|
||||
{
|
||||
if (m_current == this) {
|
||||
m_current = 0;
|
||||
EditorManager::instance()->setParent(0);
|
||||
EditorManager::instance()->hide();
|
||||
}
|
||||
if (m_mode == mode) {
|
||||
m_current = this;
|
||||
layout()->addWidget(EditorManager::instance());
|
||||
EditorManager::instance()->show();
|
||||
}
|
||||
}
|
||||
|
||||
EditorManagerPlaceHolder* EditorManagerPlaceHolder::current()
|
||||
{
|
||||
return m_current;
|
||||
}
|
||||
|
||||
// ---------------- EditorManager
|
||||
|
||||
namespace Core {
|
||||
|
||||
|
||||
struct EditorManagerPrivate {
|
||||
explicit EditorManagerPrivate(ICore *core, QWidget *parent);
|
||||
~EditorManagerPrivate();
|
||||
Internal::EditorView *m_view;
|
||||
Internal::SplitterOrView *m_splitter;
|
||||
QPointer<IEditor> m_currentEditor;
|
||||
QPointer<SplitterOrView> m_currentView;
|
||||
|
||||
ICore *m_core;
|
||||
|
||||
|
||||
// actions
|
||||
QAction *m_revertToSavedAction;
|
||||
QAction *m_saveAction;
|
||||
QAction *m_saveAsAction;
|
||||
QAction *m_closeCurrentEditorAction;
|
||||
QAction *m_closeAllEditorsAction;
|
||||
QAction *m_closeOtherEditorsAction;
|
||||
QAction *m_gotoNextDocHistoryAction;
|
||||
QAction *m_gotoPreviousDocHistoryAction;
|
||||
QAction *m_goBackAction;
|
||||
QAction *m_goForwardAction;
|
||||
QAction *m_openInExternalEditorAction;
|
||||
QAction *m_splitAction;
|
||||
QAction *m_splitSideBySideAction;
|
||||
QAction *m_removeCurrentSplitAction;
|
||||
QAction *m_removeAllSplitsAction;
|
||||
QAction *m_gotoOtherSplitAction;
|
||||
|
||||
Internal::OpenEditorsWindow *m_windowPopup;
|
||||
Core::BaseView *m_openEditorsView;
|
||||
Internal::EditorClosingCoreListener *m_coreListener;
|
||||
|
||||
QMap<QString, QVariant> m_editorStates;
|
||||
Internal::OpenEditorsViewFactory *m_openEditorsFactory;
|
||||
|
||||
QString fileFilters;
|
||||
QString selectedFilter;
|
||||
|
||||
OpenEditorsModel *m_editorModel;
|
||||
QString m_externalEditor;
|
||||
|
||||
IFile::ReloadBehavior m_reloadBehavior;
|
||||
};
|
||||
}
|
||||
|
||||
EditorManagerPrivate::EditorManagerPrivate(ICore *core, QWidget *parent) :
|
||||
m_view(0),
|
||||
m_splitter(0),
|
||||
m_core(core),
|
||||
m_revertToSavedAction(new QAction(EditorManager::tr("Revert to Saved"), parent)),
|
||||
m_saveAction(new QAction(parent)),
|
||||
m_saveAsAction(new QAction(parent)),
|
||||
m_closeCurrentEditorAction(new QAction(EditorManager::tr("Close"), parent)),
|
||||
m_closeAllEditorsAction(new QAction(EditorManager::tr("Close All"), parent)),
|
||||
m_closeOtherEditorsAction(new QAction(EditorManager::tr("Close Others"), parent)),
|
||||
m_gotoNextDocHistoryAction(new QAction(EditorManager::tr("Next Open Document in History"), parent)),
|
||||
m_gotoPreviousDocHistoryAction(new QAction(EditorManager::tr("Previous Open Document in History"), parent)),
|
||||
m_goBackAction(new QAction(QIcon(QLatin1String(":/help/images/previous.png")), EditorManager::tr("Go Back"), parent)),
|
||||
m_goForwardAction(new QAction(QIcon(QLatin1String(":/help/images/next.png")), EditorManager::tr("Go Forward"), parent)),
|
||||
m_openInExternalEditorAction(new QAction(EditorManager::tr("Open in External Editor"), parent)),
|
||||
m_windowPopup(0),
|
||||
m_coreListener(0),
|
||||
m_reloadBehavior(IFile::AskForReload)
|
||||
{
|
||||
m_editorModel = new OpenEditorsModel(parent);
|
||||
}
|
||||
|
||||
EditorManagerPrivate::~EditorManagerPrivate()
|
||||
{
|
||||
// clearNavigationHistory();
|
||||
}
|
||||
|
||||
EditorManager *EditorManager::m_instance = 0;
|
||||
|
||||
static Command *createSeparator(ActionManager *am, QObject *parent,
|
||||
const QString &name,
|
||||
const QList<int> &context)
|
||||
{
|
||||
QAction *tmpaction = new QAction(parent);
|
||||
tmpaction->setSeparator(true);
|
||||
Command *cmd = am->registerAction(tmpaction, name, context);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
EditorManager::EditorManager(ICore *core, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
m_d(new EditorManagerPrivate(core, parent))
|
||||
{
|
||||
m_instance = this;
|
||||
|
||||
connect(m_d->m_core, SIGNAL(contextAboutToChange(Core::IContext *)),
|
||||
this, SLOT(handleContextChange(Core::IContext *)));
|
||||
|
||||
const QList<int> gc = QList<int>() << Constants::C_GLOBAL_ID;
|
||||
const QList<int> editManagerContext =
|
||||
QList<int>() << m_d->m_core->uniqueIDManager()->uniqueIdentifier(Constants::C_EDITORMANAGER);
|
||||
|
||||
ActionManager *am = m_d->m_core->actionManager();
|
||||
ActionContainer *mfile = am->actionContainer(Constants::M_FILE);
|
||||
|
||||
//Revert to saved
|
||||
Command *cmd = am->registerAction(m_d->m_revertToSavedAction,
|
||||
Constants::REVERTTOSAVED, editManagerContext);
|
||||
cmd->setAttribute(Command::CA_UpdateText);
|
||||
cmd->setDefaultText(tr("Revert File to Saved"));
|
||||
mfile->addAction(cmd, Constants::G_FILE_SAVE);
|
||||
connect(m_d->m_revertToSavedAction, SIGNAL(triggered()), this, SLOT(revertToSaved()));
|
||||
|
||||
//Save Action
|
||||
am->registerAction(m_d->m_saveAction, Constants::SAVE, editManagerContext);
|
||||
connect(m_d->m_saveAction, SIGNAL(triggered()), this, SLOT(saveFile()));
|
||||
|
||||
//Save As Action
|
||||
am->registerAction(m_d->m_saveAsAction, Constants::SAVEAS, editManagerContext);
|
||||
connect(m_d->m_saveAsAction, SIGNAL(triggered()), this, SLOT(saveFileAs()));
|
||||
|
||||
//Window Menu
|
||||
ActionContainer *mwindow = am->actionContainer(Constants::M_WINDOW);
|
||||
|
||||
//Window menu separators
|
||||
QAction *tmpaction = new QAction(this);
|
||||
tmpaction->setSeparator(true);
|
||||
cmd = am->registerAction(tmpaction, QLatin1String("QtCreator.Window.Sep.Split"), editManagerContext);
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
|
||||
tmpaction = new QAction(this);
|
||||
tmpaction->setSeparator(true);
|
||||
cmd = am->registerAction(tmpaction, QLatin1String("QtCreator.Window.Sep.Navigate"), editManagerContext);
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE);
|
||||
|
||||
//Close Action
|
||||
cmd = am->registerAction(m_d->m_closeCurrentEditorAction, Constants::CLOSE, editManagerContext);
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+W")));
|
||||
cmd->setAttribute(Core::Command::CA_UpdateText);
|
||||
cmd->setDefaultText(m_d->m_closeCurrentEditorAction->text());
|
||||
mfile->addAction(cmd, Constants::G_FILE_CLOSE);
|
||||
connect(m_d->m_closeCurrentEditorAction, SIGNAL(triggered()), this, SLOT(closeEditor()));
|
||||
|
||||
//Close All Action
|
||||
cmd = am->registerAction(m_d->m_closeAllEditorsAction, Constants::CLOSEALL, editManagerContext);
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+W")));
|
||||
mfile->addAction(cmd, Constants::G_FILE_CLOSE);
|
||||
connect(m_d->m_closeAllEditorsAction, SIGNAL(triggered()), this, SLOT(closeAllEditors()));
|
||||
|
||||
//Close All Others Action
|
||||
cmd = am->registerAction(m_d->m_closeOtherEditorsAction, Constants::CLOSEOTHERS, editManagerContext);
|
||||
mfile->addAction(cmd, Constants::G_FILE_CLOSE);
|
||||
cmd->setAttribute(Core::Command::CA_UpdateText);
|
||||
connect(m_d->m_closeOtherEditorsAction, SIGNAL(triggered()), this, SLOT(closeOtherEditors()));
|
||||
|
||||
// Goto Previous In History Action
|
||||
cmd = am->registerAction(m_d->m_gotoPreviousDocHistoryAction, Constants::GOTOPREVINHISTORY, editManagerContext);
|
||||
#ifdef Q_WS_MAC
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Tab")));
|
||||
#else
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Tab")));
|
||||
#endif
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE);
|
||||
connect(m_d->m_gotoPreviousDocHistoryAction, SIGNAL(triggered()), this, SLOT(gotoPreviousDocHistory()));
|
||||
|
||||
// Goto Next In History Action
|
||||
cmd = am->registerAction(m_d->m_gotoNextDocHistoryAction, Constants::GOTONEXTINHISTORY, editManagerContext);
|
||||
#ifdef Q_WS_MAC
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Shift+Tab")));
|
||||
#else
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+Tab")));
|
||||
#endif
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE);
|
||||
connect(m_d->m_gotoNextDocHistoryAction, SIGNAL(triggered()), this, SLOT(gotoNextDocHistory()));
|
||||
|
||||
// Go back in navigation history
|
||||
cmd = am->registerAction(m_d->m_goBackAction, Constants::GO_BACK, editManagerContext);
|
||||
#ifdef Q_WS_MAC
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Left")));
|
||||
#else
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Left")));
|
||||
#endif
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE);
|
||||
connect(m_d->m_goBackAction, SIGNAL(triggered()), this, SLOT(goBackInNavigationHistory()));
|
||||
|
||||
// Go forward in navigation history
|
||||
cmd = am->registerAction(m_d->m_goForwardAction, Constants::GO_FORWARD, editManagerContext);
|
||||
#ifdef Q_WS_MAC
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Right")));
|
||||
#else
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Right")));
|
||||
#endif
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE);
|
||||
connect(m_d->m_goForwardAction, SIGNAL(triggered()), this, SLOT(goForwardInNavigationHistory()));
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
QString prefix = tr("Meta+E");
|
||||
#else
|
||||
QString prefix = tr("Ctrl+E");
|
||||
#endif
|
||||
|
||||
m_d->m_splitAction = new QAction(tr("Split"), this);
|
||||
cmd = am->registerAction(m_d->m_splitAction, Constants::SPLIT, editManagerContext);
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("%1,2").arg(prefix)));
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
connect(m_d->m_splitAction, SIGNAL(triggered()), this, SLOT(split()));
|
||||
|
||||
m_d->m_splitSideBySideAction = new QAction(tr("Split Side by Side"), this);
|
||||
cmd = am->registerAction(m_d->m_splitSideBySideAction, Constants::SPLIT_SIDE_BY_SIDE, editManagerContext);
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("%1,3").arg(prefix)));
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
connect(m_d->m_splitSideBySideAction, SIGNAL(triggered()), this, SLOT(splitSideBySide()));
|
||||
|
||||
m_d->m_removeCurrentSplitAction = new QAction(tr("Remove Current Split"), this);
|
||||
cmd = am->registerAction(m_d->m_removeCurrentSplitAction, Constants::REMOVE_CURRENT_SPLIT, editManagerContext);
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("%1,0").arg(prefix)));
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
connect(m_d->m_removeCurrentSplitAction, SIGNAL(triggered()), this, SLOT(removeCurrentSplit()));
|
||||
|
||||
m_d->m_removeAllSplitsAction = new QAction(tr("Remove All Splits"), this);
|
||||
cmd = am->registerAction(m_d->m_removeAllSplitsAction, Constants::REMOVE_ALL_SPLITS, editManagerContext);
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("%1,1").arg(prefix)));
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
connect(m_d->m_removeAllSplitsAction, SIGNAL(triggered()), this, SLOT(removeAllSplits()));
|
||||
|
||||
m_d->m_gotoOtherSplitAction = new QAction(tr("Goto Other Split"), this);
|
||||
cmd = am->registerAction(m_d->m_gotoOtherSplitAction, Constants::GOTO_OTHER_SPLIT, editManagerContext);
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("%1,o").arg(prefix)));
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
connect(m_d->m_gotoOtherSplitAction, SIGNAL(triggered()), this, SLOT(gotoOtherSplit()));
|
||||
|
||||
ActionContainer *medit = am->actionContainer(Constants::M_EDIT);
|
||||
ActionContainer *advancedMenu = am->createMenu(Constants::M_EDIT_ADVANCED);
|
||||
medit->addMenu(advancedMenu, Constants::G_EDIT_ADVANCED);
|
||||
advancedMenu->menu()->setTitle(tr("&Advanced"));
|
||||
advancedMenu->appendGroup(Constants::G_EDIT_FORMAT);
|
||||
advancedMenu->appendGroup(Constants::G_EDIT_COLLAPSING);
|
||||
advancedMenu->appendGroup(Constants::G_EDIT_BLOCKS);
|
||||
advancedMenu->appendGroup(Constants::G_EDIT_FONT);
|
||||
advancedMenu->appendGroup(Constants::G_EDIT_EDITOR);
|
||||
|
||||
// Advanced menu separators
|
||||
cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Collapsing"), editManagerContext);
|
||||
advancedMenu->addAction(cmd, Constants::G_EDIT_COLLAPSING);
|
||||
cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Blocks"), editManagerContext);
|
||||
advancedMenu->addAction(cmd, Constants::G_EDIT_BLOCKS);
|
||||
cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Font"), editManagerContext);
|
||||
advancedMenu->addAction(cmd, Constants::G_EDIT_FONT);
|
||||
cmd = createSeparator(am, this, QLatin1String("QtCreator.Edit.Sep.Editor"), editManagerContext);
|
||||
advancedMenu->addAction(cmd, Constants::G_EDIT_EDITOR);
|
||||
|
||||
cmd = am->registerAction(m_d->m_openInExternalEditorAction, Constants::OPEN_IN_EXTERNAL_EDITOR, editManagerContext);
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Alt+V,Alt+I")));
|
||||
advancedMenu->addAction(cmd, Constants::G_EDIT_EDITOR);
|
||||
connect(m_d->m_openInExternalEditorAction, SIGNAL(triggered()), this, SLOT(openInExternalEditor()));
|
||||
|
||||
// Connect to VariableManager for CURRENT_DOCUMENT variable setting
|
||||
VariableManager *vm = VariableManager::instance();
|
||||
connect(this, SIGNAL(currentEditorChanged(Core::IEditor *)),
|
||||
vm, SLOT(updateCurrentDocument(Core::IEditor *)));
|
||||
|
||||
|
||||
// other setup
|
||||
m_d->m_splitter = new SplitterOrView(m_d->m_editorModel);
|
||||
m_d->m_view = m_d->m_splitter->view();
|
||||
|
||||
|
||||
QHBoxLayout *layout = new QHBoxLayout(this);
|
||||
layout->setMargin(0);
|
||||
layout->setSpacing(0);
|
||||
layout->addWidget(m_d->m_splitter);
|
||||
|
||||
updateActions();
|
||||
|
||||
m_d->m_windowPopup = new OpenEditorsWindow(this);
|
||||
}
|
||||
|
||||
EditorManager::~EditorManager()
|
||||
{
|
||||
if (m_d->m_core) {
|
||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
if (m_d->m_coreListener) {
|
||||
pm->removeObject(m_d->m_coreListener);
|
||||
delete m_d->m_coreListener;
|
||||
}
|
||||
pm->removeObject(m_d->m_openEditorsFactory);
|
||||
delete m_d->m_openEditorsFactory;
|
||||
}
|
||||
delete m_d;
|
||||
}
|
||||
|
||||
void EditorManager::init()
|
||||
{
|
||||
QList<int> context;
|
||||
context << m_d->m_core->uniqueIDManager()->uniqueIdentifier("QtCreator.OpenDocumentsView");
|
||||
|
||||
m_d->m_coreListener = new EditorClosingCoreListener(this);
|
||||
|
||||
pluginManager()->addObject(m_d->m_coreListener);
|
||||
|
||||
m_d->m_openEditorsFactory = new OpenEditorsViewFactory();
|
||||
pluginManager()->addObject(m_d->m_openEditorsFactory);
|
||||
}
|
||||
|
||||
QString EditorManager::defaultExternalEditor() const
|
||||
{
|
||||
#ifdef Q_OS_UNIX
|
||||
return ConsoleProcess::defaultTerminalEmulator() + QLatin1String(
|
||||
# ifdef Q_OS_MAC
|
||||
" -async"
|
||||
# endif
|
||||
" -geom %Wx%H+%x+%y -e vi %f +%l +\"normal %c|\"");
|
||||
#else
|
||||
return QLatin1String("notepad %f");
|
||||
#endif
|
||||
}
|
||||
|
||||
void EditorManager::removeEditor(IEditor *editor)
|
||||
{
|
||||
bool isDuplicate = m_d->m_editorModel->isDuplicate(editor);
|
||||
m_d->m_editorModel->removeEditor(editor);
|
||||
if (!isDuplicate) {
|
||||
m_d->m_core->fileManager()->removeFile(editor->file());
|
||||
}
|
||||
m_d->m_core->removeContextObject(editor);
|
||||
}
|
||||
|
||||
void EditorManager::handleContextChange(Core::IContext *context)
|
||||
{
|
||||
if (debugEditorManager)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
IEditor *editor = context ? qobject_cast<IEditor*>(context) : 0;
|
||||
if (editor) {
|
||||
setCurrentEditor(editor);
|
||||
} else {
|
||||
updateActions();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorManager::setCurrentEditor(IEditor *editor, bool ignoreNavigationHistory)
|
||||
{
|
||||
if (editor)
|
||||
setCurrentView(0);
|
||||
|
||||
if (m_d->m_currentEditor == editor)
|
||||
return;
|
||||
if (m_d->m_currentEditor && !ignoreNavigationHistory)
|
||||
addCurrentPositionToNavigationHistory();
|
||||
|
||||
m_d->m_currentEditor = editor;
|
||||
if (editor) {
|
||||
if (SplitterOrView *splitterOrView = m_d->m_splitter->findView(editor))
|
||||
splitterOrView->view()->setCurrentEditor(editor);
|
||||
m_d->m_view->updateEditorHistory(editor); // the global view should have a complete history
|
||||
}
|
||||
updateActions();
|
||||
emit currentEditorChanged(editor);
|
||||
}
|
||||
|
||||
|
||||
void EditorManager::setCurrentView(Core::Internal::SplitterOrView *view)
|
||||
{
|
||||
if (view == m_d->m_currentView)
|
||||
return;
|
||||
|
||||
SplitterOrView *old = m_d->m_currentView;
|
||||
m_d->m_currentView = view;
|
||||
|
||||
if (old)
|
||||
old->update();
|
||||
if (view)
|
||||
view->update();
|
||||
|
||||
if (view && !view->editor())
|
||||
view->setFocus();
|
||||
}
|
||||
|
||||
Core::Internal::SplitterOrView *EditorManager::currentSplitterOrView() const
|
||||
{
|
||||
SplitterOrView *view = m_d->m_currentView;
|
||||
if (!view)
|
||||
view = m_d->m_currentEditor?
|
||||
m_d->m_splitter->findView(m_d->m_currentEditor):
|
||||
m_d->m_splitter->findFirstView();
|
||||
if (!view)
|
||||
return m_d->m_splitter;
|
||||
return view;
|
||||
}
|
||||
|
||||
Core::Internal::EditorView *EditorManager::currentEditorView() const
|
||||
{
|
||||
return currentSplitterOrView()->view();
|
||||
}
|
||||
|
||||
|
||||
|
||||
QList<IEditor *> EditorManager::editorsForFileName(const QString &filename) const
|
||||
{
|
||||
QList<IEditor *> found;
|
||||
QString fixedname = FileManager::fixFileName(filename);
|
||||
foreach (IEditor *editor, openedEditors()) {
|
||||
if (fixedname == FileManager::fixFileName(editor->file()->fileName()))
|
||||
found << editor;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
QList<IEditor *> EditorManager::editorsForFile(IFile *file) const
|
||||
{
|
||||
QList<IEditor *> found;
|
||||
foreach (IEditor *editor, openedEditors()) {
|
||||
if (editor->file() == file)
|
||||
found << editor;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
IEditor *EditorManager::currentEditor() const
|
||||
{
|
||||
return m_d->m_currentEditor;
|
||||
}
|
||||
|
||||
void EditorManager::emptyView(Core::Internal::EditorView *view)
|
||||
{
|
||||
if (!view)
|
||||
return;
|
||||
|
||||
QList<IEditor *> editors = view->editors();
|
||||
foreach (IEditor *editor, editors) {
|
||||
if (!m_d->m_editorModel->isDuplicate(editor)) {
|
||||
editors.removeAll(editor);
|
||||
view->removeEditor(editor);
|
||||
continue;
|
||||
}
|
||||
emit editorAboutToClose(editor);
|
||||
removeEditor(editor);
|
||||
view->removeEditor(editor);
|
||||
}
|
||||
emit editorsClosed(editors);
|
||||
foreach (IEditor *editor, editors) {
|
||||
delete editor;
|
||||
}
|
||||
}
|
||||
|
||||
void EditorManager::closeView(Core::Internal::EditorView *view)
|
||||
{
|
||||
if (!view)
|
||||
return;
|
||||
|
||||
if (view == m_d->m_view) {
|
||||
if (IEditor *e = view->currentEditor())
|
||||
closeEditors(QList<IEditor *>() << e);
|
||||
return;
|
||||
}
|
||||
|
||||
emptyView(view);
|
||||
|
||||
SplitterOrView *splitterOrView = m_d->m_splitter->findView(view);
|
||||
Q_ASSERT(splitterOrView);
|
||||
Q_ASSERT(splitterOrView->view() == view);
|
||||
SplitterOrView *splitter = m_d->m_splitter->findSplitter(splitterOrView);
|
||||
Q_ASSERT(splitterOrView->hasEditors() == false);
|
||||
splitterOrView->hide();
|
||||
delete splitterOrView;
|
||||
|
||||
splitter->unsplit();
|
||||
|
||||
SplitterOrView *newCurrent = splitter->findFirstView();
|
||||
if (newCurrent) {
|
||||
if (newCurrent->editor())
|
||||
activateEditor(newCurrent->view(), newCurrent->editor());
|
||||
else
|
||||
setCurrentView(newCurrent);
|
||||
}
|
||||
}
|
||||
|
||||
QList<IEditor*>
|
||||
EditorManager::editorsForFiles(QList<IFile*> files) const
|
||||
{
|
||||
const QList<IEditor *> editors = openedEditors();
|
||||
QSet<IEditor *> found;
|
||||
foreach (IFile *file, files) {
|
||||
foreach (IEditor *editor, editors) {
|
||||
if (editor->file() == file && !found.contains(editor)) {
|
||||
found << editor;
|
||||
}
|
||||
}
|
||||
}
|
||||
return found.toList();
|
||||
}
|
||||
|
||||
QList<IFile *> EditorManager::filesForEditors(QList<IEditor *> editors) const
|
||||
{
|
||||
QSet<IEditor *> handledEditors;
|
||||
QList<IFile *> files;
|
||||
foreach (IEditor *editor, editors) {
|
||||
if (!handledEditors.contains(editor)) {
|
||||
files << editor->file();
|
||||
handledEditors.insert(editor);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
bool EditorManager::closeAllEditors(bool askAboutModifiedEditors)
|
||||
{
|
||||
m_d->m_editorModel->removeAllRestoredEditors();
|
||||
if (closeEditors(openedEditors(), askAboutModifiedEditors)) {
|
||||
// m_d->clearNavigationHistory();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EditorManager::closeOtherEditors(IEditor *editor)
|
||||
{
|
||||
m_d->m_editorModel->removeAllRestoredEditors();
|
||||
QList<IEditor*> editors = openedEditors();
|
||||
editors.removeAll(editor);
|
||||
closeEditors(editors, true);
|
||||
}
|
||||
|
||||
|
||||
void EditorManager::closeOtherEditors()
|
||||
{
|
||||
IEditor *current = currentEditor();
|
||||
QTC_ASSERT(current, return);
|
||||
closeOtherEditors(current);
|
||||
}
|
||||
|
||||
|
||||
// SLOT connected to action
|
||||
// since this is potentially called in the event handler of the editor
|
||||
// we simply postpone it with a single shot timer
|
||||
void EditorManager::closeEditor()
|
||||
{
|
||||
closeEditor(m_d->m_currentEditor);
|
||||
}
|
||||
|
||||
void EditorManager::closeEditor(Core::IEditor *editor)
|
||||
{
|
||||
if (!editor)
|
||||
return;
|
||||
closeEditors(QList<IEditor *>() << editor);
|
||||
}
|
||||
|
||||
void EditorManager::closeEditor(const QModelIndex &index)
|
||||
{
|
||||
IEditor *editor = index.data(Qt::UserRole).value<Core::IEditor*>();
|
||||
if (editor)
|
||||
closeEditor(editor);
|
||||
else
|
||||
m_d->m_editorModel->removeEditor(index);
|
||||
}
|
||||
|
||||
bool EditorManager::closeEditors(const QList<IEditor*> editorsToClose, bool askAboutModifiedEditors)
|
||||
{
|
||||
if (editorsToClose.isEmpty())
|
||||
return true;
|
||||
|
||||
SplitterOrView *currentSplitterOrView = this->currentSplitterOrView();
|
||||
|
||||
bool closingFailed = false;
|
||||
QList<IEditor*> acceptedEditors;
|
||||
//ask all core listeners to check whether the editor can be closed
|
||||
const QList<ICoreListener *> listeners =
|
||||
pluginManager()->getObjects<ICoreListener>();
|
||||
foreach (IEditor *editor, editorsToClose) {
|
||||
bool editorAccepted = true;
|
||||
if (m_d->m_editorModel->isDuplicate(editor))
|
||||
editor = m_d->m_editorModel->originalForDuplicate(editor);
|
||||
foreach (ICoreListener *listener, listeners) {
|
||||
if (!listener->editorAboutToClose(editor)) {
|
||||
editorAccepted = false;
|
||||
closingFailed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (editorAccepted)
|
||||
acceptedEditors.append(editor);
|
||||
}
|
||||
if (acceptedEditors.isEmpty())
|
||||
return false;
|
||||
//ask whether to save modified files
|
||||
if (askAboutModifiedEditors) {
|
||||
bool cancelled = false;
|
||||
QList<IFile*> list = m_d->m_core->fileManager()->
|
||||
saveModifiedFiles(filesForEditors(acceptedEditors), &cancelled);
|
||||
if (cancelled)
|
||||
return false;
|
||||
if (!list.isEmpty()) {
|
||||
closingFailed = true;
|
||||
QSet<IEditor*> skipSet = editorsForFiles(list).toSet();
|
||||
acceptedEditors = acceptedEditors.toSet().subtract(skipSet).toList();
|
||||
}
|
||||
}
|
||||
if (acceptedEditors.isEmpty())
|
||||
return false;
|
||||
|
||||
// add duplicates
|
||||
foreach(IEditor *editor, acceptedEditors)
|
||||
acceptedEditors += m_d->m_editorModel->duplicatesFor(editor);
|
||||
|
||||
QList<EditorView*> closedViews;
|
||||
|
||||
// remove the editors
|
||||
foreach (IEditor *editor, acceptedEditors) {
|
||||
emit editorAboutToClose(editor);
|
||||
if (!editor->file()->fileName().isEmpty()) {
|
||||
QByteArray state = editor->saveState();
|
||||
if (!state.isEmpty())
|
||||
m_d->m_editorStates.insert(editor->file()->fileName(), QVariant(state));
|
||||
}
|
||||
|
||||
removeEditor(editor);
|
||||
if (SplitterOrView *view = m_d->m_splitter->findView(editor)) {
|
||||
if (editor == view->view()->currentEditor())
|
||||
closedViews += view->view();
|
||||
view->view()->removeEditor(editor);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (EditorView *view, closedViews) {
|
||||
IEditor *newCurrent = view->currentEditor();
|
||||
if (!newCurrent)
|
||||
newCurrent = pickUnusedEditor();
|
||||
if (newCurrent) {
|
||||
activateEditor(view, newCurrent, NoActivate);
|
||||
} else {
|
||||
QModelIndex idx = m_d->m_editorModel->firstRestoredEditor();
|
||||
if (idx.isValid())
|
||||
activateEditor(idx, view, NoActivate);
|
||||
}
|
||||
}
|
||||
|
||||
emit editorsClosed(acceptedEditors);
|
||||
|
||||
foreach (IEditor *editor, acceptedEditors) {
|
||||
delete editor;
|
||||
}
|
||||
|
||||
if (currentSplitterOrView) {
|
||||
if (IEditor *editor = currentSplitterOrView->editor())
|
||||
activateEditor(currentSplitterOrView->view(), editor);
|
||||
}
|
||||
|
||||
if (!currentEditor())
|
||||
emit currentEditorChanged(0);
|
||||
|
||||
return !closingFailed;
|
||||
}
|
||||
|
||||
void EditorManager::closeDuplicate(Core::IEditor *editor)
|
||||
{
|
||||
|
||||
IEditor *original = editor;
|
||||
if (m_d->m_editorModel->isDuplicate(editor))
|
||||
original= m_d->m_editorModel->originalForDuplicate(editor);
|
||||
QList<IEditor *> duplicates = m_d->m_editorModel->duplicatesFor(original);
|
||||
|
||||
if (duplicates.isEmpty()) {
|
||||
closeEditor(editor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (original== editor)
|
||||
m_d->m_editorModel->makeOriginal(duplicates.first());
|
||||
|
||||
SplitterOrView *currentSplitterOrView = this->currentSplitterOrView();
|
||||
|
||||
emit editorAboutToClose(editor);
|
||||
|
||||
EditorView *view = m_d->m_splitter->findView(editor)->view();
|
||||
removeEditor(editor);
|
||||
view->removeEditor(editor);
|
||||
|
||||
IEditor *newCurrent = view->currentEditor();
|
||||
if (!newCurrent)
|
||||
newCurrent = pickUnusedEditor();
|
||||
if (newCurrent) {
|
||||
activateEditor(view, newCurrent, NoActivate);
|
||||
} else {
|
||||
QModelIndex idx = m_d->m_editorModel->firstRestoredEditor();
|
||||
if (idx.isValid())
|
||||
activateEditor(idx, view, NoActivate);
|
||||
}
|
||||
|
||||
emit editorsClosed(QList<IEditor*>() << editor);
|
||||
delete editor;
|
||||
if (currentSplitterOrView) {
|
||||
if (IEditor *currentEditor = currentSplitterOrView->editor())
|
||||
activateEditor(currentSplitterOrView->view(), currentEditor);
|
||||
}
|
||||
}
|
||||
|
||||
Core::IEditor *EditorManager::pickUnusedEditor() const
|
||||
{
|
||||
foreach (IEditor *editor, openedEditors()) {
|
||||
SplitterOrView *view = m_d->m_splitter->findView(editor);
|
||||
if (!view || view->editor() != editor)
|
||||
return editor;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Core::IEditor *EditorManager::activateEditor(const QModelIndex &index, Internal::EditorView *view, OpenEditorFlags flags)
|
||||
{
|
||||
IEditor *editor = index.data(Qt::UserRole).value<IEditor*>();
|
||||
if (editor) {
|
||||
return activateEditor(view, editor, flags);
|
||||
}
|
||||
|
||||
QString fileName = index.data(Qt::UserRole + 1).toString();
|
||||
QByteArray kind = index.data(Qt::UserRole + 2).toByteArray();
|
||||
return openEditor(view, fileName, kind, flags);
|
||||
}
|
||||
|
||||
Core::IEditor *EditorManager::placeEditor(Core::Internal::EditorView *view, Core::IEditor *editor)
|
||||
{
|
||||
Q_ASSERT(view && editor);
|
||||
|
||||
if (view->currentEditor() && view->currentEditor()->file() == editor->file())
|
||||
editor = view->currentEditor();
|
||||
|
||||
if (!view->hasEditor(editor)) {
|
||||
bool duplicateSupported = editor->duplicateSupported();
|
||||
if (SplitterOrView *sourceView = m_d->m_splitter->findView(editor)) {
|
||||
if (editor != sourceView->editor() || !duplicateSupported) {
|
||||
sourceView->view()->removeEditor(editor);
|
||||
view->addEditor(editor);
|
||||
view->setCurrentEditor(editor);
|
||||
if (!sourceView->editor()) {
|
||||
if (IEditor *replacement = pickUnusedEditor()) {
|
||||
sourceView->view()->addEditor(replacement);
|
||||
}
|
||||
}
|
||||
return editor;
|
||||
} else if (duplicateSupported) {
|
||||
editor = duplicateEditor(editor);
|
||||
Q_ASSERT(editor);
|
||||
m_d->m_editorModel->makeOriginal(editor);
|
||||
}
|
||||
}
|
||||
view->addEditor(editor);
|
||||
}
|
||||
return editor;
|
||||
}
|
||||
|
||||
Core::IEditor *EditorManager::activateEditor(Core::IEditor *editor, OpenEditorFlags flags)
|
||||
{
|
||||
return activateEditor(0, editor, flags);
|
||||
}
|
||||
|
||||
Core::IEditor *EditorManager::activateEditor(Core::Internal::EditorView *view, Core::IEditor *editor, OpenEditorFlags flags)
|
||||
{
|
||||
if (!view)
|
||||
view = currentEditorView();
|
||||
|
||||
Q_ASSERT(view);
|
||||
|
||||
if (!editor) {
|
||||
if (!m_d->m_currentEditor)
|
||||
setCurrentEditor(0, (flags & IgnoreNavigationHistory));
|
||||
return 0;
|
||||
}
|
||||
|
||||
editor = placeEditor(view, editor);
|
||||
|
||||
if (!(flags & NoActivate)) {
|
||||
setCurrentEditor(editor, (flags & IgnoreNavigationHistory));
|
||||
if (!(flags & NoModeSwitch))
|
||||
ensureEditorManagerVisible();
|
||||
if (isVisible())
|
||||
editor->widget()->setFocus();
|
||||
}
|
||||
return editor;
|
||||
}
|
||||
|
||||
Core::IEditor *EditorManager::activateEditor(Core::Internal::EditorView *view, Core::IFile *file, OpenEditorFlags flags)
|
||||
{
|
||||
QList<IEditor*> editors = editorsForFile(file);
|
||||
Q_ASSERT(!editors.isEmpty());
|
||||
return activateEditor(view, editors.first(), flags);
|
||||
}
|
||||
|
||||
/* For something that has a 'QStringList mimeTypes' (IEditorFactory
|
||||
* or IExternalEditor), find the one best matching the mimetype passed in.
|
||||
* Recurse over the parent classes of the mimetype to find them. */
|
||||
template <class EditorFactoryLike>
|
||||
static void mimeTypeFactoryRecursion(const MimeDatabase *db,
|
||||
const MimeType &mimeType,
|
||||
const QList<EditorFactoryLike*> &allFactories,
|
||||
bool firstMatchOnly,
|
||||
QList<EditorFactoryLike*> *list)
|
||||
{
|
||||
typedef typename QList<EditorFactoryLike*>::const_iterator EditorFactoryLikeListConstIterator;
|
||||
// Loop factories to find type
|
||||
const QString type = mimeType.type();
|
||||
const EditorFactoryLikeListConstIterator fcend = allFactories.constEnd();
|
||||
for (EditorFactoryLikeListConstIterator fit = allFactories.constBegin(); fit != fcend; ++fit) {
|
||||
// Exclude duplicates when recursing over xml or C++ -> C -> text.
|
||||
EditorFactoryLike *factory = *fit;
|
||||
if (!list->contains(factory) && factory->mimeTypes().contains(type)) {
|
||||
list->push_back(*fit);
|
||||
if (firstMatchOnly)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Any parent mime type classes? -> recurse
|
||||
QStringList parentTypes = mimeType.subClassesOf();
|
||||
if (parentTypes.empty())
|
||||
return;
|
||||
const QStringList::const_iterator pcend = parentTypes .constEnd();
|
||||
for (QStringList::const_iterator pit = parentTypes .constBegin(); pit != pcend; ++pit) {
|
||||
if (const MimeType parent = db->findByType(*pit))
|
||||
mimeTypeFactoryRecursion(db, parent, allFactories, firstMatchOnly, list);
|
||||
}
|
||||
}
|
||||
|
||||
EditorManager::EditorFactoryList
|
||||
EditorManager::editorFactories(const MimeType &mimeType, bool bestMatchOnly) const
|
||||
{
|
||||
EditorFactoryList rc;
|
||||
const EditorFactoryList allFactories = pluginManager()->getObjects<IEditorFactory>();
|
||||
mimeTypeFactoryRecursion(m_d->m_core->mimeDatabase(), mimeType, allFactories, bestMatchOnly, &rc);
|
||||
if (debugEditorManager)
|
||||
qDebug() << Q_FUNC_INFO << mimeType.type() << " returns " << rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
EditorManager::ExternalEditorList
|
||||
EditorManager::externalEditors(const MimeType &mimeType, bool bestMatchOnly) const
|
||||
{
|
||||
ExternalEditorList rc;
|
||||
const ExternalEditorList allEditors = pluginManager()->getObjects<IExternalEditor>();
|
||||
mimeTypeFactoryRecursion(m_d->m_core->mimeDatabase(), mimeType, allEditors, bestMatchOnly, &rc);
|
||||
if (debugEditorManager)
|
||||
qDebug() << Q_FUNC_INFO << mimeType.type() << " returns " << rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* For something that has a 'QString kind' (IEditorFactory
|
||||
* or IExternalEditor), find the one matching a kind. */
|
||||
template <class EditorFactoryLike>
|
||||
inline EditorFactoryLike *findByKind(ExtensionSystem::PluginManager *pm,
|
||||
const QString &kind)
|
||||
{
|
||||
const QList<EditorFactoryLike *> factories = pm->template getObjects<EditorFactoryLike>();
|
||||
foreach(EditorFactoryLike *efl, factories)
|
||||
if (kind == efl->kind())
|
||||
return efl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
IEditor *EditorManager::createEditor(const QString &editorKind,
|
||||
const QString &fileName)
|
||||
{
|
||||
typedef QList<IEditorFactory*> FactoryList;
|
||||
if (debugEditorManager)
|
||||
qDebug() << Q_FUNC_INFO << editorKind << fileName;
|
||||
|
||||
|
||||
EditorFactoryList factories;
|
||||
if (editorKind.isEmpty()) {
|
||||
// Find by mime type
|
||||
MimeType mimeType = m_d->m_core->mimeDatabase()->findByFile(QFileInfo(fileName));
|
||||
if (!mimeType) {
|
||||
qWarning("%s unable to determine mime type of %s/%s. Falling back to text/plain",
|
||||
Q_FUNC_INFO, fileName.toUtf8().constData(), editorKind.toUtf8().constData());
|
||||
mimeType = m_d->m_core->mimeDatabase()->findByType(QLatin1String("text/plain"));
|
||||
}
|
||||
factories = editorFactories(mimeType, true);
|
||||
} else {
|
||||
// Find by editor kind
|
||||
if (IEditorFactory *factory = findByKind<IEditorFactory>(pluginManager(), editorKind))
|
||||
factories.push_back(factory);
|
||||
}
|
||||
if (factories.empty()) {
|
||||
qWarning("%s: unable to find an editor factory for the file '%s', editor kind '%s'.",
|
||||
Q_FUNC_INFO, fileName.toUtf8().constData(), editorKind.toUtf8().constData());
|
||||
return 0;
|
||||
}
|
||||
|
||||
IEditor *editor = factories.front()->createEditor(this);
|
||||
if (editor)
|
||||
connect(editor, SIGNAL(changed()), this, SLOT(updateActions()));
|
||||
if (editor)
|
||||
emit editorCreated(editor, fileName);
|
||||
return editor;
|
||||
}
|
||||
|
||||
void EditorManager::addEditor(IEditor *editor, bool isDuplicate)
|
||||
{
|
||||
if (!editor)
|
||||
return;
|
||||
m_d->m_core->addContextObject(editor);
|
||||
|
||||
m_d->m_editorModel->addEditor(editor, isDuplicate);
|
||||
if (!isDuplicate) {
|
||||
m_d->m_core->fileManager()->addFile(editor->file());
|
||||
if (!editor->isTemporary()) {
|
||||
m_d->m_core->fileManager()->addToRecentFiles(editor->file()->fileName());
|
||||
}
|
||||
}
|
||||
emit editorOpened(editor);
|
||||
}
|
||||
|
||||
// Run the OpenWithDialog and return the editor kind
|
||||
// selected by the user.
|
||||
QString EditorManager::getOpenWithEditorKind(const QString &fileName,
|
||||
bool *isExternalEditor) const
|
||||
{
|
||||
// Collect editors that can open the file
|
||||
const MimeType mt = m_d->m_core->mimeDatabase()->findByFile(fileName);
|
||||
if (!mt)
|
||||
return QString();
|
||||
QStringList allEditorKinds;
|
||||
QStringList externalEditorKinds;
|
||||
// Built-in
|
||||
const EditorFactoryList editors = editorFactories(mt, false);
|
||||
const int size = editors.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
allEditorKinds.push_back(editors.at(i)->kind());
|
||||
}
|
||||
// External editors
|
||||
const ExternalEditorList exEditors = externalEditors(mt, false);
|
||||
const int esize = exEditors.size();
|
||||
for (int i = 0; i < esize; i++) {
|
||||
externalEditorKinds.push_back(exEditors.at(i)->kind());
|
||||
allEditorKinds.push_back(exEditors.at(i)->kind());
|
||||
}
|
||||
if (allEditorKinds.empty())
|
||||
return QString();
|
||||
// Run dialog.
|
||||
OpenWithDialog dialog(fileName, m_d->m_core->mainWindow());
|
||||
dialog.setEditors(allEditorKinds);
|
||||
dialog.setCurrentEditor(0);
|
||||
if (dialog.exec() != QDialog::Accepted)
|
||||
return QString();
|
||||
const QString selectedKind = dialog.editor();
|
||||
if (isExternalEditor)
|
||||
*isExternalEditor = externalEditorKinds.contains(selectedKind);
|
||||
return selectedKind;
|
||||
}
|
||||
|
||||
static QString formatFileFilters(const Core::ICore *core, QString *selectedFilter)
|
||||
{
|
||||
QString rc;
|
||||
// Compile list of filter strings. If we find a glob matching all files,
|
||||
// put it last and set it as default selectedFilter.
|
||||
QStringList filters = core->mimeDatabase()->filterStrings();
|
||||
filters.sort();
|
||||
selectedFilter->clear();
|
||||
if (filters.empty())
|
||||
return rc;
|
||||
const QString filterSeparator = QLatin1String(";;");
|
||||
bool hasAllFilter = false;
|
||||
const int size = filters.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
const QString &filterString = filters.at(i);
|
||||
if (filterString.isEmpty()) { // binary editor
|
||||
hasAllFilter = true;
|
||||
} else {
|
||||
if (!rc.isEmpty())
|
||||
rc += filterSeparator;
|
||||
rc += filterString;
|
||||
}
|
||||
}
|
||||
if (hasAllFilter) {
|
||||
// prepend all files filter
|
||||
// prepending instead of appending to work around a but in Qt/Mac
|
||||
QString allFilesFilter = EditorManager::tr("All Files (*)");
|
||||
if (!rc.isEmpty())
|
||||
allFilesFilter += filterSeparator;
|
||||
rc.prepend(allFilesFilter);
|
||||
*selectedFilter = allFilesFilter;
|
||||
} else {
|
||||
*selectedFilter = filters.front();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
IEditor *EditorManager::openEditor(const QString &fileName, const QString &editorKind,
|
||||
EditorManager::OpenEditorFlags flags)
|
||||
{
|
||||
return openEditor(0, fileName, editorKind, flags);
|
||||
}
|
||||
|
||||
IEditor *EditorManager::openEditor(Core::Internal::EditorView *view, const QString &fileName,
|
||||
const QString &editorKind, EditorManager::OpenEditorFlags flags)
|
||||
{
|
||||
if (debugEditorManager)
|
||||
qDebug() << Q_FUNC_INFO << fileName << editorKind;
|
||||
|
||||
if (fileName.isEmpty())
|
||||
return 0;
|
||||
|
||||
const QList<IEditor *> editors = editorsForFileName(fileName);
|
||||
if (!editors.isEmpty()) {
|
||||
return activateEditor(view, editors.first(), flags);
|
||||
}
|
||||
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||||
IEditor *editor = createEditor(editorKind, fileName);
|
||||
if (!editor || !editor->open(fileName)) {
|
||||
QApplication::restoreOverrideCursor();
|
||||
QMessageBox::critical(m_d->m_core->mainWindow(), tr("Opening File"), tr("Cannot open file %1!").arg(QDir::toNativeSeparators(fileName)));
|
||||
delete editor;
|
||||
editor = 0;
|
||||
return 0;
|
||||
}
|
||||
addEditor(editor);
|
||||
|
||||
IEditor *result= activateEditor(view, editor, flags);
|
||||
if (editor == result)
|
||||
restoreEditorState(editor);
|
||||
QApplication::restoreOverrideCursor();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool EditorManager::openExternalEditor(const QString &fileName, const QString &editorKind)
|
||||
{
|
||||
IExternalEditor *ee = findByKind<IExternalEditor>(pluginManager(), editorKind);
|
||||
if (!ee)
|
||||
return false;
|
||||
QString errorMessage;
|
||||
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||||
const bool ok = ee->startEditor(fileName, &errorMessage);
|
||||
QApplication::restoreOverrideCursor();
|
||||
if (!ok)
|
||||
QMessageBox::critical(m_d->m_core->mainWindow(), tr("Opening File"), errorMessage);
|
||||
return ok;
|
||||
}
|
||||
|
||||
QStringList EditorManager::getOpenFileNames() const
|
||||
{
|
||||
static QString dir = QDir::homePath();
|
||||
if (m_d->fileFilters.isEmpty())
|
||||
m_d->fileFilters = formatFileFilters(m_d->m_core, &m_d->selectedFilter);
|
||||
|
||||
QString currentFile = ICore::instance()->fileManager()->currentFile();
|
||||
if (!currentFile.isEmpty()) {
|
||||
const QFileInfo fi(currentFile);
|
||||
dir = fi.absolutePath();
|
||||
}
|
||||
|
||||
QStringList files = QFileDialog::getOpenFileNames(m_d->m_core->mainWindow(), tr("Open File"),
|
||||
dir, m_d->fileFilters, &m_d->selectedFilter);
|
||||
if (!files.isEmpty())
|
||||
dir = QFileInfo(files.at(0)).absolutePath();
|
||||
return files;
|
||||
}
|
||||
|
||||
void EditorManager::ensureEditorManagerVisible()
|
||||
{
|
||||
if (!isVisible())
|
||||
m_d->m_core->modeManager()->activateMode(Constants::MODE_EDIT);
|
||||
}
|
||||
|
||||
IEditor *EditorManager::openEditorWithContents(const QString &editorKind,
|
||||
QString *titlePattern,
|
||||
const QString &contents)
|
||||
{
|
||||
if (debugEditorManager)
|
||||
qDebug() << Q_FUNC_INFO << editorKind << titlePattern << contents;
|
||||
|
||||
if (editorKind.isEmpty())
|
||||
return 0;
|
||||
|
||||
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||||
IEditor *edt = createEditor(editorKind);
|
||||
if (!edt) {
|
||||
QApplication::restoreOverrideCursor();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!edt->createNew(contents)) {
|
||||
QApplication::restoreOverrideCursor();
|
||||
delete edt;
|
||||
edt = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString title = edt->displayName();
|
||||
|
||||
if (title.isEmpty() && titlePattern) {
|
||||
const QChar dollar = QLatin1Char('$');
|
||||
const QChar dot = QLatin1Char('.');
|
||||
|
||||
QString base = *titlePattern;
|
||||
if (base.isEmpty())
|
||||
base = QLatin1String("unnamed$");
|
||||
if (base.contains(dollar)) {
|
||||
int i = 1;
|
||||
QSet<QString> docnames;
|
||||
foreach (IEditor *editor, openedEditors()) {
|
||||
QString name = editor->file()->fileName();
|
||||
if (name.isEmpty()) {
|
||||
name = editor->displayName();
|
||||
name.remove(QLatin1Char('*'));
|
||||
} else {
|
||||
name = QFileInfo(name).completeBaseName();
|
||||
}
|
||||
docnames << name;
|
||||
}
|
||||
|
||||
do {
|
||||
title = base;
|
||||
title.replace(QString(dollar), QString::number(i++));
|
||||
} while (docnames.contains(title));
|
||||
} else {
|
||||
title = *titlePattern;
|
||||
}
|
||||
}
|
||||
*titlePattern = title;
|
||||
edt->setDisplayName(title);
|
||||
addEditor(edt);
|
||||
QApplication::restoreOverrideCursor();
|
||||
return edt;
|
||||
}
|
||||
|
||||
bool EditorManager::hasEditor(const QString &fileName) const
|
||||
{
|
||||
return !editorsForFileName(fileName).isEmpty();
|
||||
}
|
||||
|
||||
void EditorManager::restoreEditorState(IEditor *editor)
|
||||
{
|
||||
QTC_ASSERT(editor, return);
|
||||
QString fileName = editor->file()->fileName();
|
||||
if (m_d->m_editorStates.contains(fileName))
|
||||
editor->restoreState(m_d->m_editorStates.value(fileName).toByteArray());
|
||||
}
|
||||
|
||||
bool EditorManager::saveEditor(IEditor *editor)
|
||||
{
|
||||
return saveFile(editor);
|
||||
}
|
||||
|
||||
bool EditorManager::saveFile(IEditor *editor)
|
||||
{
|
||||
if (!editor)
|
||||
editor = currentEditor();
|
||||
if (!editor)
|
||||
return false;
|
||||
|
||||
IFile *file = editor->file();
|
||||
file->checkPermissions();
|
||||
|
||||
const QString &fileName = file->fileName();
|
||||
|
||||
if (fileName.isEmpty())
|
||||
return saveFileAs(editor);
|
||||
|
||||
bool success = false;
|
||||
|
||||
// try saving, no matter what isReadOnly tells us
|
||||
m_d->m_core->fileManager()->blockFileChange(file);
|
||||
success = file->save(fileName);
|
||||
m_d->m_core->fileManager()->unblockFileChange(file);
|
||||
|
||||
if (!success) {
|
||||
MakeWritableResult answer =
|
||||
makeEditorWritable(editor);
|
||||
if (answer == Failed)
|
||||
return false;
|
||||
if (answer == SavedAs)
|
||||
return true;
|
||||
|
||||
file->checkPermissions();
|
||||
|
||||
m_d->m_core->fileManager()->blockFileChange(file);
|
||||
success = file->save(fileName);
|
||||
m_d->m_core->fileManager()->unblockFileChange(file);
|
||||
}
|
||||
|
||||
if (success && !editor->isTemporary())
|
||||
m_d->m_core->fileManager()->addToRecentFiles(editor->file()->fileName());
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
EditorManager::ReadOnlyAction
|
||||
EditorManager::promptReadOnlyFile(const QString &fileName,
|
||||
const IVersionControl *versionControl,
|
||||
QWidget *parent,
|
||||
bool displaySaveAsButton)
|
||||
{
|
||||
QMessageBox msgBox(QMessageBox::Question, tr("File is Read Only"),
|
||||
tr("The file %1 is read only.").arg(QDir::toNativeSeparators(fileName)),
|
||||
QMessageBox::Cancel, parent);
|
||||
|
||||
QPushButton *sccButton = 0;
|
||||
if (versionControl && versionControl->supportsOperation(IVersionControl::OpenOperation))
|
||||
sccButton = msgBox.addButton(tr("Open with VCS (%1)").arg(versionControl->name()), QMessageBox::AcceptRole);
|
||||
|
||||
QPushButton *makeWritableButton = msgBox.addButton(tr("Make writable"), QMessageBox::AcceptRole);
|
||||
|
||||
QPushButton *saveAsButton = 0;
|
||||
if (displaySaveAsButton)
|
||||
saveAsButton = msgBox.addButton(tr("Save as ..."), QMessageBox::ActionRole);
|
||||
|
||||
msgBox.setDefaultButton(sccButton ? sccButton : makeWritableButton);
|
||||
msgBox.exec();
|
||||
|
||||
QAbstractButton *clickedButton = msgBox.clickedButton();
|
||||
if (clickedButton == sccButton)
|
||||
return RO_OpenVCS;
|
||||
if (clickedButton == makeWritableButton)
|
||||
return RO_MakeWriteable;
|
||||
if (clickedButton == saveAsButton)
|
||||
return RO_SaveAs;
|
||||
return RO_Cancel;
|
||||
}
|
||||
|
||||
|
||||
MakeWritableResult
|
||||
EditorManager::makeEditorWritable(IEditor *editor)
|
||||
{
|
||||
if (!editor || !editor->file())
|
||||
return Failed;
|
||||
QString directory = QFileInfo(editor->file()->fileName()).absolutePath();
|
||||
IVersionControl *versionControl = m_d->m_core->vcsManager()->findVersionControlForDirectory(directory);
|
||||
IFile *file = editor->file();
|
||||
const QString &fileName = file->fileName();
|
||||
|
||||
switch (promptReadOnlyFile(fileName, versionControl, m_d->m_core->mainWindow(), true)) {
|
||||
case RO_OpenVCS:
|
||||
if (!versionControl->vcsOpen(fileName)) {
|
||||
QMessageBox::warning(m_d->m_core->mainWindow(), tr("Failed!"), tr("Could not open the file for editing with SCC."));
|
||||
return Failed;
|
||||
}
|
||||
file->checkPermissions();
|
||||
return OpenedWithVersionControl;
|
||||
case RO_MakeWriteable: {
|
||||
const bool permsOk = QFile::setPermissions(fileName, QFile::permissions(fileName) | QFile::WriteUser);
|
||||
if (!permsOk) {
|
||||
QMessageBox::warning(m_d->m_core->mainWindow(), tr("Failed!"), tr("Could not set permissions to writable."));
|
||||
return Failed;
|
||||
}
|
||||
}
|
||||
file->checkPermissions();
|
||||
return MadeWritable;
|
||||
case RO_SaveAs :
|
||||
return saveFileAs(editor) ? SavedAs : Failed;
|
||||
case RO_Cancel:
|
||||
break;
|
||||
}
|
||||
return Failed;
|
||||
}
|
||||
|
||||
bool EditorManager::saveFileAs(IEditor *editor)
|
||||
{
|
||||
if (!editor)
|
||||
editor = currentEditor();
|
||||
if (!editor)
|
||||
return false;
|
||||
|
||||
QString absoluteFilePath = m_d->m_core->fileManager()->getSaveAsFileName(editor->file());
|
||||
if (absoluteFilePath.isEmpty())
|
||||
return false;
|
||||
if (absoluteFilePath != editor->file()->fileName()) {
|
||||
const QList<IEditor *> existList = editorsForFileName(absoluteFilePath);
|
||||
if (!existList.isEmpty()) {
|
||||
closeEditors(existList, false);
|
||||
}
|
||||
}
|
||||
|
||||
m_d->m_core->fileManager()->blockFileChange(editor->file());
|
||||
const bool success = editor->file()->save(absoluteFilePath);
|
||||
m_d->m_core->fileManager()->unblockFileChange(editor->file());
|
||||
editor->file()->checkPermissions();
|
||||
|
||||
if (success && !editor->isTemporary())
|
||||
m_d->m_core->fileManager()->addToRecentFiles(editor->file()->fileName());
|
||||
|
||||
updateActions();
|
||||
return success;
|
||||
}
|
||||
|
||||
void EditorManager::gotoNextDocHistory()
|
||||
{
|
||||
OpenEditorsWindow *dialog = windowPopup();
|
||||
if (dialog->isVisible()) {
|
||||
dialog->selectNextEditor();
|
||||
} else {
|
||||
EditorView *view = currentEditorView();
|
||||
dialog->setEditors(m_d->m_view, view, m_d->m_editorModel);
|
||||
dialog->selectNextEditor();
|
||||
showWindowPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorManager::gotoPreviousDocHistory()
|
||||
{
|
||||
OpenEditorsWindow *dialog = windowPopup();
|
||||
if (dialog->isVisible()) {
|
||||
dialog->selectPreviousEditor();
|
||||
} else {
|
||||
EditorView *view = currentEditorView();
|
||||
dialog->setEditors(m_d->m_view, view, m_d->m_editorModel);
|
||||
dialog->selectPreviousEditor();
|
||||
showWindowPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorManager::makeCurrentEditorWritable()
|
||||
{
|
||||
if (IEditor* curEditor = currentEditor())
|
||||
makeEditorWritable(curEditor);
|
||||
}
|
||||
|
||||
void EditorManager::updateActions()
|
||||
{
|
||||
QString fName;
|
||||
IEditor *curEditor = currentEditor();
|
||||
int openedCount = openedEditors().count() + m_d->m_editorModel->restoredEditorCount();
|
||||
if (curEditor) {
|
||||
if (!curEditor->file()->fileName().isEmpty()) {
|
||||
QFileInfo fi(curEditor->file()->fileName());
|
||||
fName = fi.fileName();
|
||||
} else {
|
||||
fName = curEditor->displayName();
|
||||
}
|
||||
|
||||
|
||||
if (curEditor->file()->isModified() && curEditor->file()->isReadOnly()) {
|
||||
// we are about to change a read-only file, warn user
|
||||
showEditorInfoBar(QLatin1String("Core.EditorManager.MakeWritable"),
|
||||
tr("<b>Warning:</b> You are changing a read-only file."),
|
||||
tr("Make writable"), this, SLOT(makeCurrentEditorWritable()));
|
||||
} else {
|
||||
hideEditorInfoBar(QLatin1String("Core.EditorManager.MakeWritable"));
|
||||
}
|
||||
}
|
||||
|
||||
m_d->m_saveAction->setEnabled(curEditor != 0 && curEditor->file()->isModified());
|
||||
m_d->m_saveAsAction->setEnabled(curEditor != 0 && curEditor->file()->isSaveAsAllowed());
|
||||
m_d->m_revertToSavedAction->setEnabled(curEditor != 0
|
||||
&& !curEditor->file()->fileName().isEmpty() && curEditor->file()->isModified());
|
||||
|
||||
QString quotedName;
|
||||
if (!fName.isEmpty())
|
||||
quotedName = '"' + fName + '"';
|
||||
m_d->m_saveAsAction->setText(tr("Save %1 As...").arg(quotedName));
|
||||
m_d->m_saveAction->setText(tr("&Save %1").arg(quotedName));
|
||||
m_d->m_revertToSavedAction->setText(tr("Revert %1 to Saved").arg(quotedName));
|
||||
|
||||
|
||||
m_d->m_closeCurrentEditorAction->setEnabled(curEditor != 0);
|
||||
m_d->m_closeCurrentEditorAction->setText(tr("Close %1").arg(quotedName));
|
||||
m_d->m_closeAllEditorsAction->setEnabled(openedCount > 0);
|
||||
m_d->m_closeOtherEditorsAction->setEnabled(openedCount > 1);
|
||||
m_d->m_closeOtherEditorsAction->setText((openedCount > 1 ? tr("Close All Except %1").arg(quotedName) : tr("Close Others")));
|
||||
|
||||
m_d->m_gotoNextDocHistoryAction->setEnabled(m_d->m_editorModel->rowCount() != 0);
|
||||
m_d->m_gotoPreviousDocHistoryAction->setEnabled(m_d->m_editorModel->rowCount() != 0);
|
||||
EditorView *view = currentEditorView();
|
||||
m_d->m_goBackAction->setEnabled(view ? view->canGoBack() : false);
|
||||
m_d->m_goForwardAction->setEnabled(view ? view->canGoForward() : false);
|
||||
|
||||
bool hasSplitter = m_d->m_splitter->isSplitter();
|
||||
m_d->m_removeCurrentSplitAction->setEnabled(hasSplitter);
|
||||
m_d->m_removeAllSplitsAction->setEnabled(hasSplitter);
|
||||
m_d->m_gotoOtherSplitAction->setEnabled(hasSplitter);
|
||||
|
||||
m_d->m_openInExternalEditorAction->setEnabled(curEditor != 0);
|
||||
}
|
||||
|
||||
QList<IEditor*> EditorManager::openedEditors() const
|
||||
{
|
||||
return m_d->m_editorModel->editors();
|
||||
}
|
||||
|
||||
OpenEditorsModel *EditorManager::openedEditorsModel() const
|
||||
{
|
||||
return m_d->m_editorModel;
|
||||
}
|
||||
|
||||
void EditorManager::addCurrentPositionToNavigationHistory(IEditor *editor, const QByteArray &saveState)
|
||||
{
|
||||
currentEditorView()->addCurrentPositionToNavigationHistory(editor, saveState);
|
||||
updateActions();
|
||||
}
|
||||
|
||||
void EditorManager::goBackInNavigationHistory()
|
||||
{
|
||||
currentEditorView()->goBackInNavigationHistory();
|
||||
updateActions();
|
||||
ensureEditorManagerVisible();
|
||||
return;
|
||||
}
|
||||
|
||||
void EditorManager::goForwardInNavigationHistory()
|
||||
{
|
||||
currentEditorView()->goForwardInNavigationHistory();
|
||||
updateActions();
|
||||
ensureEditorManagerVisible();
|
||||
}
|
||||
|
||||
OpenEditorsWindow *EditorManager::windowPopup() const
|
||||
{
|
||||
return m_d->m_windowPopup;
|
||||
}
|
||||
|
||||
void EditorManager::showWindowPopup() const
|
||||
{
|
||||
const QPoint p(mapToGlobal(QPoint(0, 0)));
|
||||
m_d->m_windowPopup->move((width()-m_d->m_windowPopup->width())/2 + p.x(),
|
||||
(height()-m_d->m_windowPopup->height())/2 + p.y());
|
||||
m_d->m_windowPopup->setVisible(true);
|
||||
}
|
||||
|
||||
QByteArray EditorManager::saveState() const
|
||||
{
|
||||
QByteArray bytes;
|
||||
QDataStream stream(&bytes, QIODevice::WriteOnly);
|
||||
|
||||
stream << QByteArray("EditorManagerV4");
|
||||
|
||||
QList<IEditor *> editors = openedEditors();
|
||||
foreach (IEditor *editor, editors) {
|
||||
if (!editor->file()->fileName().isEmpty()) {
|
||||
QByteArray state = editor->saveState();
|
||||
if (!state.isEmpty())
|
||||
m_d->m_editorStates.insert(editor->file()->fileName(), QVariant(state));
|
||||
}
|
||||
}
|
||||
|
||||
stream << m_d->m_editorStates;
|
||||
|
||||
QList<OpenEditorsModel::Entry> entries = m_d->m_editorModel->entries();
|
||||
stream << entries.count();
|
||||
|
||||
foreach (OpenEditorsModel::Entry entry, entries) {
|
||||
stream << entry.fileName() << entry.displayName() << entry.kind();
|
||||
}
|
||||
|
||||
stream << m_d->m_splitter->saveState();
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
bool EditorManager::restoreState(const QByteArray &state)
|
||||
{
|
||||
closeAllEditors(true);
|
||||
removeAllSplits();
|
||||
QDataStream stream(state);
|
||||
|
||||
QByteArray version;
|
||||
stream >> version;
|
||||
|
||||
if (version != "EditorManagerV4")
|
||||
return false;
|
||||
|
||||
QMap<QString, QVariant> editorstates;
|
||||
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
stream >> editorstates;
|
||||
|
||||
QMapIterator<QString, QVariant> i(editorstates);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
m_d->m_editorStates.insert(i.key(), i.value());
|
||||
}
|
||||
|
||||
int editorCount = 0;
|
||||
stream >> editorCount;
|
||||
while (--editorCount >= 0) {
|
||||
QString fileName;
|
||||
stream >> fileName;
|
||||
QString displayName;
|
||||
stream >> displayName;
|
||||
QByteArray kind;
|
||||
stream >> kind;
|
||||
|
||||
if (!fileName.isEmpty() && !displayName.isEmpty()){
|
||||
m_d->m_editorModel->addRestoredEditor(fileName, displayName, kind);
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray splitterstates;
|
||||
stream >> splitterstates;
|
||||
m_d->m_splitter->restoreState(splitterstates);
|
||||
|
||||
// splitting and stuff results in focus trouble, that's why we set the focus again after restoration
|
||||
ensureEditorManagerVisible();
|
||||
if (m_d->m_currentEditor) {
|
||||
m_d->m_currentEditor->widget()->setFocus();
|
||||
} else if (Core::Internal::SplitterOrView *view = currentSplitterOrView()) {
|
||||
if (IEditor *e = view->editor())
|
||||
e->widget()->setFocus();
|
||||
else if (view->view())
|
||||
view->view()->setFocus();
|
||||
}
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char * const documentStatesKey = "EditorManager/DocumentStates";
|
||||
static const char * const externalEditorKey = "EditorManager/ExternalEditorCommand";
|
||||
static const char * const reloadBehaviorKey = "EditorManager/ReloadBehavior";
|
||||
|
||||
void EditorManager::saveSettings()
|
||||
{
|
||||
SettingsDatabase *settings = m_d->m_core->settingsDatabase();
|
||||
settings->setValue(QLatin1String(documentStatesKey), m_d->m_editorStates);
|
||||
settings->setValue(QLatin1String(externalEditorKey), m_d->m_externalEditor);
|
||||
settings->setValue(QLatin1String(reloadBehaviorKey), m_d->m_reloadBehavior);
|
||||
}
|
||||
|
||||
void EditorManager::readSettings()
|
||||
{
|
||||
// Backward compatibility to old locations for these settings
|
||||
QSettings *qs = m_d->m_core->settings();
|
||||
if (qs->contains(QLatin1String(documentStatesKey))) {
|
||||
m_d->m_editorStates = qs->value(QLatin1String(documentStatesKey))
|
||||
.value<QMap<QString, QVariant> >();
|
||||
qs->remove(QLatin1String(documentStatesKey));
|
||||
}
|
||||
if (qs->contains(QLatin1String(externalEditorKey))) {
|
||||
m_d->m_externalEditor = qs->value(QLatin1String(externalEditorKey)).toString();
|
||||
qs->remove(QLatin1String(externalEditorKey));
|
||||
}
|
||||
|
||||
SettingsDatabase *settings = m_d->m_core->settingsDatabase();
|
||||
if (settings->contains(QLatin1String(documentStatesKey)))
|
||||
m_d->m_editorStates = settings->value(QLatin1String(documentStatesKey))
|
||||
.value<QMap<QString, QVariant> >();
|
||||
if (settings->contains(QLatin1String(externalEditorKey)))
|
||||
m_d->m_externalEditor = settings->value(QLatin1String(externalEditorKey)).toString();
|
||||
|
||||
if (settings->contains(QLatin1String(reloadBehaviorKey)))
|
||||
m_d->m_reloadBehavior = (IFile::ReloadBehavior)settings->value(QLatin1String(reloadBehaviorKey)).toInt();
|
||||
}
|
||||
|
||||
|
||||
void EditorManager::revertToSaved()
|
||||
{
|
||||
IEditor *currEditor = currentEditor();
|
||||
if (!currEditor)
|
||||
return;
|
||||
const QString fileName = currEditor->file()->fileName();
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
if (currEditor->file()->isModified()) {
|
||||
QMessageBox msgBox(QMessageBox::Question, tr("Revert to Saved"),
|
||||
tr("You will lose your current changes if you proceed reverting %1.").arg(QDir::toNativeSeparators(fileName)),
|
||||
QMessageBox::Yes|QMessageBox::No, m_d->m_core->mainWindow());
|
||||
msgBox.button(QMessageBox::Yes)->setText(tr("Proceed"));
|
||||
msgBox.button(QMessageBox::No)->setText(tr("Cancel"));
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
msgBox.setEscapeButton(QMessageBox::No);
|
||||
if (msgBox.exec() == QMessageBox::No)
|
||||
return;
|
||||
|
||||
}
|
||||
IFile::ReloadBehavior temp = IFile::ReloadAll;
|
||||
currEditor->file()->modified(&temp);
|
||||
}
|
||||
|
||||
void EditorManager::showEditorInfoBar(const QString &kind,
|
||||
const QString &infoText,
|
||||
const QString &buttonText,
|
||||
QObject *object, const char *member)
|
||||
{
|
||||
|
||||
currentEditorView()->showEditorInfoBar(kind, infoText, buttonText, object, member);
|
||||
}
|
||||
|
||||
|
||||
void EditorManager::hideEditorInfoBar(const QString &kind)
|
||||
{
|
||||
Core::Internal::EditorView *cev = currentEditorView();
|
||||
if (cev)
|
||||
cev->hideEditorInfoBar(kind);
|
||||
}
|
||||
|
||||
void EditorManager::showEditorStatusBar(const QString &kind,
|
||||
const QString &infoText,
|
||||
const QString &buttonText,
|
||||
QObject *object, const char *member)
|
||||
{
|
||||
|
||||
currentEditorView()->showEditorStatusBar(kind, infoText, buttonText, object, member);
|
||||
}
|
||||
|
||||
void EditorManager::hideEditorStatusBar(const QString &kind)
|
||||
{
|
||||
currentEditorView()->hideEditorStatusBar(kind);
|
||||
}
|
||||
|
||||
QString EditorManager::externalEditorHelpText() const
|
||||
{
|
||||
QString help = tr(
|
||||
"<table border=1 cellspacing=0 cellpadding=3>"
|
||||
"<tr><th>Variable</th><th>Expands to</th></tr>"
|
||||
"<tr><td>%f</td><td>file name</td></tr>"
|
||||
"<tr><td>%l</td><td>current line number</td></tr>"
|
||||
"<tr><td>%c</td><td>current column number</td></tr>"
|
||||
"<tr><td>%x</td><td>editor's x position on screen</td></tr>"
|
||||
"<tr><td>%y</td><td>editor's y position on screen</td></tr>"
|
||||
"<tr><td>%w</td><td>editor's width in pixels</td></tr>"
|
||||
"<tr><td>%h</td><td>editor's height in pixels</td></tr>"
|
||||
"<tr><td>%W</td><td>editor's width in characters</td></tr>"
|
||||
"<tr><td>%H</td><td>editor's height in characters</td></tr>"
|
||||
"<tr><td>%%</td><td>%</td></tr>"
|
||||
"</table>");
|
||||
return help;
|
||||
}
|
||||
|
||||
void EditorManager::openInExternalEditor()
|
||||
{
|
||||
QString command = m_d->m_externalEditor;
|
||||
if (command.isEmpty())
|
||||
command = defaultExternalEditor();
|
||||
|
||||
if (command.isEmpty())
|
||||
return;
|
||||
|
||||
IEditor *editor = currentEditor();
|
||||
if (!editor)
|
||||
return;
|
||||
if (editor->file()->isModified()) {
|
||||
bool cancelled = false;
|
||||
QList<IFile*> list = m_d->m_core->fileManager()->
|
||||
saveModifiedFiles(QList<IFile*>() << editor->file(), &cancelled);
|
||||
if (cancelled)
|
||||
return;
|
||||
}
|
||||
|
||||
QRect rect = editor->widget()->rect();
|
||||
QFont font = editor->widget()->font();
|
||||
QFontMetrics fm(font);
|
||||
rect.moveTo(editor->widget()->mapToGlobal(QPoint(0,0)));
|
||||
|
||||
QString pre = command;
|
||||
QString cmd;
|
||||
for (int i = 0; i < pre.size(); ++i) {
|
||||
QChar c = pre.at(i);
|
||||
if (c == QLatin1Char('%') && i < pre.size()-1) {
|
||||
c = pre.at(++i);
|
||||
QString s;
|
||||
if (c == QLatin1Char('f'))
|
||||
s = editor->file()->fileName();
|
||||
else if (c == QLatin1Char('l'))
|
||||
s = QString::number(editor->currentLine());
|
||||
else if (c == QLatin1Char('c'))
|
||||
s = QString::number(editor->currentColumn());
|
||||
else if (c == QLatin1Char('x'))
|
||||
s = QString::number(rect.x());
|
||||
else if (c == QLatin1Char('y'))
|
||||
s = QString::number(rect.y());
|
||||
else if (c == QLatin1Char('w'))
|
||||
s = QString::number(rect.width());
|
||||
else if (c == QLatin1Char('h'))
|
||||
s = QString::number(rect.height());
|
||||
else if (c == QLatin1Char('W'))
|
||||
s = QString::number(rect.width() / fm.width(QLatin1Char('x')));
|
||||
else if (c == QLatin1Char('H'))
|
||||
s = QString::number(rect.height() / fm.lineSpacing());
|
||||
else if (c == QLatin1Char('%'))
|
||||
s = c;
|
||||
else {
|
||||
s = QLatin1Char('%');
|
||||
cmd += c;
|
||||
}
|
||||
cmd += s;
|
||||
continue;
|
||||
|
||||
}
|
||||
cmd += c;
|
||||
}
|
||||
|
||||
QProcess::startDetached(cmd);
|
||||
}
|
||||
|
||||
void EditorManager::setExternalEditor(const QString &editor)
|
||||
{
|
||||
if (editor.isEmpty() || editor == defaultExternalEditor())
|
||||
m_d->m_externalEditor = defaultExternalEditor();
|
||||
else
|
||||
m_d->m_externalEditor = editor;
|
||||
}
|
||||
|
||||
QString EditorManager::externalEditor() const
|
||||
{
|
||||
if (m_d->m_externalEditor.isEmpty())
|
||||
return defaultExternalEditor();
|
||||
return m_d->m_externalEditor;
|
||||
}
|
||||
|
||||
void EditorManager::setReloadBehavior(IFile::ReloadBehavior behavior)
|
||||
{
|
||||
m_d->m_reloadBehavior = behavior;
|
||||
}
|
||||
|
||||
IFile::ReloadBehavior EditorManager::reloadBehavior() const
|
||||
{
|
||||
return m_d->m_reloadBehavior;
|
||||
}
|
||||
|
||||
Core::IEditor *EditorManager::duplicateEditor(Core::IEditor *editor)
|
||||
{
|
||||
if (!editor->duplicateSupported())
|
||||
return 0;
|
||||
|
||||
IEditor *duplicate = editor->duplicate(0);
|
||||
duplicate->restoreState(editor->saveState());
|
||||
emit editorCreated(duplicate, duplicate->file()->fileName());
|
||||
addEditor(duplicate, true);
|
||||
return duplicate;
|
||||
}
|
||||
|
||||
void EditorManager::split(Qt::Orientation orientation)
|
||||
{
|
||||
SplitterOrView *view = m_d->m_currentView;
|
||||
if (!view)
|
||||
view = m_d->m_currentEditor ? m_d->m_splitter->findView(m_d->m_currentEditor)
|
||||
: m_d->m_splitter->findFirstView();
|
||||
if (view && !view->splitter()) {
|
||||
view->split(orientation);
|
||||
}
|
||||
updateActions();
|
||||
}
|
||||
|
||||
void EditorManager::split()
|
||||
{
|
||||
split(Qt::Vertical);
|
||||
}
|
||||
|
||||
void EditorManager::splitSideBySide()
|
||||
{
|
||||
split(Qt::Horizontal);
|
||||
}
|
||||
|
||||
void EditorManager::removeCurrentSplit()
|
||||
{
|
||||
SplitterOrView *viewToClose = m_d->m_currentView;
|
||||
if (!viewToClose && m_d->m_currentEditor)
|
||||
viewToClose = m_d->m_splitter->findView(m_d->m_currentEditor);
|
||||
|
||||
if (!viewToClose || viewToClose->isSplitter() || viewToClose == m_d->m_splitter)
|
||||
return;
|
||||
|
||||
closeView(viewToClose->view());
|
||||
updateActions();
|
||||
}
|
||||
|
||||
void EditorManager::removeAllSplits()
|
||||
{
|
||||
if (!m_d->m_splitter->isSplitter())
|
||||
return;
|
||||
IEditor *editor = m_d->m_currentEditor;
|
||||
m_d->m_currentEditor = 0; // trigger update below
|
||||
if (editor && m_d->m_editorModel->isDuplicate(editor))
|
||||
editor = m_d->m_editorModel->originalForDuplicate(editor);
|
||||
m_d->m_splitter->unsplitAll();
|
||||
if (!editor)
|
||||
editor = pickUnusedEditor();
|
||||
activateEditor(editor);
|
||||
}
|
||||
|
||||
void EditorManager::gotoOtherSplit()
|
||||
{
|
||||
if (m_d->m_splitter->isSplitter()) {
|
||||
SplitterOrView *currentView = m_d->m_currentView;
|
||||
if (!currentView && m_d->m_currentEditor)
|
||||
currentView = m_d->m_splitter->findView(m_d->m_currentEditor);
|
||||
if (!currentView)
|
||||
currentView = m_d->m_splitter->findFirstView();
|
||||
SplitterOrView *view = m_d->m_splitter->findNextView(currentView);
|
||||
if (!view)
|
||||
view = m_d->m_splitter->findFirstView();
|
||||
if (view) {
|
||||
if (IEditor *editor = view->editor()) {
|
||||
setCurrentEditor(editor, true);
|
||||
editor->widget()->setFocus();
|
||||
} else {
|
||||
setCurrentView(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//===================EditorClosingCoreListener======================
|
||||
|
||||
EditorClosingCoreListener::EditorClosingCoreListener(EditorManager *em)
|
||||
: m_em(em)
|
||||
{
|
||||
}
|
||||
|
||||
bool EditorClosingCoreListener::editorAboutToClose(IEditor *)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorClosingCoreListener::coreAboutToClose()
|
||||
{
|
||||
// Do not ask for files to save.
|
||||
// MainWindow::closeEvent has already done that.
|
||||
return m_em->closeAllEditors(false);
|
||||
}
|
@ -1,292 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef EDITORMANAGER_H
|
||||
#define EDITORMANAGER_H
|
||||
|
||||
#include "../core_global.h"
|
||||
|
||||
#include <coreplugin/icorelistener.h>
|
||||
#include <coreplugin/ifile.h>
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QSettings;
|
||||
class QModelIndex;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
|
||||
class EditorGroup;
|
||||
class IContext;
|
||||
class ICore;
|
||||
class IEditor;
|
||||
class IEditorFactory;
|
||||
class IExternalEditor;
|
||||
class MimeType;
|
||||
class IFile;
|
||||
class IMode;
|
||||
class IVersionControl;
|
||||
|
||||
enum MakeWritableResult {
|
||||
OpenedWithVersionControl,
|
||||
MadeWritable,
|
||||
SavedAs,
|
||||
Failed
|
||||
};
|
||||
|
||||
struct EditorManagerPrivate;
|
||||
class OpenEditorsModel;
|
||||
|
||||
namespace Internal {
|
||||
class OpenEditorsWindow;
|
||||
class EditorView;
|
||||
class SplitterOrView;
|
||||
|
||||
class EditorClosingCoreListener;
|
||||
class OpenEditorsViewFactory;
|
||||
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
class CORE_EXPORT EditorManagerPlaceHolder : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
EditorManagerPlaceHolder(Core::IMode *mode, QWidget *parent = 0);
|
||||
~EditorManagerPlaceHolder();
|
||||
static EditorManagerPlaceHolder* current();
|
||||
private slots:
|
||||
void currentModeChanged(Core::IMode *);
|
||||
private:
|
||||
Core::IMode *m_mode;
|
||||
static EditorManagerPlaceHolder* m_current;
|
||||
};
|
||||
|
||||
class CORE_EXPORT EditorManager : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
typedef QList<IEditorFactory*> EditorFactoryList;
|
||||
typedef QList<IExternalEditor*> ExternalEditorList;
|
||||
|
||||
explicit EditorManager(ICore *core, QWidget *parent);
|
||||
virtual ~EditorManager();
|
||||
void init();
|
||||
static EditorManager *instance() { return m_instance; }
|
||||
|
||||
enum OpenEditorFlag {
|
||||
NoActivate = 1,
|
||||
IgnoreNavigationHistory = 2,
|
||||
NoModeSwitch = 4
|
||||
};
|
||||
Q_DECLARE_FLAGS(OpenEditorFlags, OpenEditorFlag)
|
||||
|
||||
IEditor *openEditor(const QString &fileName,
|
||||
const QString &editorKind = QString(),
|
||||
OpenEditorFlags flags = 0);
|
||||
IEditor *openEditorWithContents(const QString &editorKind,
|
||||
QString *titlePattern = 0,
|
||||
const QString &contents = QString());
|
||||
|
||||
bool openExternalEditor(const QString &fileName, const QString &editorKind);
|
||||
|
||||
QStringList getOpenFileNames() const;
|
||||
QString getOpenWithEditorKind(const QString &fileName, bool *isExternalEditor = 0) const;
|
||||
|
||||
void ensureEditorManagerVisible();
|
||||
bool hasEditor(const QString &fileName) const;
|
||||
QList<IEditor *> editorsForFileName(const QString &filename) const;
|
||||
QList<IEditor *> editorsForFile(IFile *file) const;
|
||||
|
||||
IEditor *currentEditor() const;
|
||||
IEditor *activateEditor(IEditor *editor, OpenEditorFlags flags = 0);
|
||||
IEditor *activateEditor(const QModelIndex &index, Internal::EditorView *view = 0, OpenEditorFlags = 0);
|
||||
IEditor *activateEditor(Core::Internal::EditorView *view, Core::IFile*file, OpenEditorFlags flags = 0);
|
||||
|
||||
QList<IEditor*> openedEditors() const;
|
||||
|
||||
OpenEditorsModel *openedEditorsModel() const;
|
||||
void closeEditor(const QModelIndex &index);
|
||||
void closeOtherEditors(IEditor *editor);
|
||||
|
||||
QList<IEditor*> editorsForFiles(QList<IFile*> files) const;
|
||||
//QList<EditorGroup *> editorGroups() const;
|
||||
void addCurrentPositionToNavigationHistory(IEditor *editor = 0, const QByteArray &saveState = QByteArray());
|
||||
|
||||
bool saveEditor(IEditor *editor);
|
||||
|
||||
bool closeEditors(const QList<IEditor *> editorsToClose, bool askAboutModifiedEditors = true);
|
||||
|
||||
MakeWritableResult makeEditorWritable(IEditor *editor);
|
||||
|
||||
QByteArray saveState() const;
|
||||
bool restoreState(const QByteArray &state);
|
||||
|
||||
IEditor *restoreEditor(QString fileName, QString editorKind, EditorGroup *group);
|
||||
|
||||
void saveSettings();
|
||||
void readSettings();
|
||||
|
||||
Internal::OpenEditorsWindow *windowPopup() const;
|
||||
void showWindowPopup() const;
|
||||
|
||||
void showEditorInfoBar(const QString &kind,
|
||||
const QString &infoText,
|
||||
const QString &buttonText = QString(),
|
||||
QObject *object = 0, const char *member = 0);
|
||||
|
||||
void hideEditorInfoBar(const QString &kind);
|
||||
|
||||
void showEditorStatusBar(const QString &kind,
|
||||
const QString &infoText,
|
||||
const QString &buttonText = QString(),
|
||||
QObject *object = 0, const char *member = 0);
|
||||
|
||||
void hideEditorStatusBar(const QString &kind);
|
||||
|
||||
EditorFactoryList editorFactories(const MimeType &mimeType, bool bestMatchOnly = true) const;
|
||||
ExternalEditorList externalEditors(const MimeType &mimeType, bool bestMatchOnly = true) const;
|
||||
|
||||
void setExternalEditor(const QString &);
|
||||
QString externalEditor() const;
|
||||
QString defaultExternalEditor() const;
|
||||
QString externalEditorHelpText() const;
|
||||
|
||||
void setReloadBehavior(IFile::ReloadBehavior behavior);
|
||||
IFile::ReloadBehavior reloadBehavior() const;
|
||||
|
||||
// Helper to display a message dialog when encountering a read-only
|
||||
// file, prompting the user about how to make it writeable.
|
||||
enum ReadOnlyAction { RO_Cancel, RO_OpenVCS, RO_MakeWriteable, RO_SaveAs };
|
||||
|
||||
static ReadOnlyAction promptReadOnlyFile(const QString &fileName,
|
||||
const IVersionControl *versionControl,
|
||||
QWidget *parent,
|
||||
bool displaySaveAsButton = false);
|
||||
|
||||
signals:
|
||||
void currentEditorChanged(Core::IEditor *editor);
|
||||
void editorCreated(Core::IEditor *editor, const QString &fileName);
|
||||
void editorOpened(Core::IEditor *editor);
|
||||
void editorAboutToClose(Core::IEditor *editor);
|
||||
void editorsClosed(QList<Core::IEditor *> editors);
|
||||
|
||||
public slots:
|
||||
bool closeAllEditors(bool askAboutModifiedEditors = true);
|
||||
void openInExternalEditor();
|
||||
|
||||
bool saveFile(Core::IEditor *editor = 0);
|
||||
bool saveFileAs(Core::IEditor *editor = 0);
|
||||
void revertToSaved();
|
||||
void closeEditor();
|
||||
void closeOtherEditors();
|
||||
|
||||
private slots:
|
||||
void gotoNextDocHistory();
|
||||
void gotoPreviousDocHistory();
|
||||
void handleContextChange(Core::IContext *context);
|
||||
void updateActions();
|
||||
void makeCurrentEditorWritable();
|
||||
|
||||
public slots:
|
||||
void goBackInNavigationHistory();
|
||||
void goForwardInNavigationHistory();
|
||||
void split(Qt::Orientation orientation);
|
||||
void split();
|
||||
void splitSideBySide();
|
||||
void removeCurrentSplit();
|
||||
void removeAllSplits();
|
||||
void gotoOtherSplit();
|
||||
|
||||
private:
|
||||
QList<IFile *> filesForEditors(QList<IEditor *> editors) const;
|
||||
IEditor *createEditor(const QString &mimeType = QString(),
|
||||
const QString &fileName = QString());
|
||||
void addEditor(IEditor *editor, bool isDuplicate = false);
|
||||
void removeEditor(IEditor *editor);
|
||||
|
||||
void restoreEditorState(IEditor *editor);
|
||||
|
||||
IEditor *placeEditor(Core::Internal::EditorView *view, Core::IEditor *editor);
|
||||
Core::IEditor *duplicateEditor(IEditor *editor);
|
||||
void setCurrentEditor(IEditor *editor, bool ignoreNavigationHistory = false);
|
||||
void setCurrentView(Core::Internal::SplitterOrView *view);
|
||||
IEditor *activateEditor(Core::Internal::EditorView *view, Core::IEditor *editor, OpenEditorFlags flags = 0);
|
||||
IEditor *openEditor(Core::Internal::EditorView *view, const QString &fileName,
|
||||
const QString &editorKind = QString(),
|
||||
OpenEditorFlags flags = 0);
|
||||
Core::Internal::SplitterOrView *currentSplitterOrView() const;
|
||||
|
||||
void closeEditor(Core::IEditor *editor);
|
||||
void closeDuplicate(Core::IEditor *editor);
|
||||
void closeView(Core::Internal::EditorView *view);
|
||||
void emptyView(Core::Internal::EditorView *view);
|
||||
Core::Internal::EditorView *currentEditorView() const;
|
||||
IEditor *pickUnusedEditor() const;
|
||||
|
||||
|
||||
static EditorManager *m_instance;
|
||||
EditorManagerPrivate *m_d;
|
||||
|
||||
friend class Core::Internal::SplitterOrView;
|
||||
friend class Core::Internal::EditorView;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(Core::EditorManager::OpenEditorFlags);
|
||||
|
||||
|
||||
//===================EditorClosingCoreListener======================
|
||||
|
||||
namespace Core {
|
||||
namespace Internal {
|
||||
|
||||
class EditorClosingCoreListener : public ICoreListener
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EditorClosingCoreListener(EditorManager *em);
|
||||
bool editorAboutToClose(IEditor *editor);
|
||||
bool coreAboutToClose();
|
||||
|
||||
private:
|
||||
EditorManager *m_em;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
#endif // EDITORMANAGER_H
|
@ -1,665 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "editorsplitter.h"
|
||||
|
||||
#include "coreconstants.h"
|
||||
#include "editormanager.h"
|
||||
#include "icore.h"
|
||||
#include "minisplitter.h"
|
||||
#include "openeditorswindow.h"
|
||||
#include "stackededitorgroup.h"
|
||||
#include "uniqueidmanager.h"
|
||||
#include "actionmanager/actionmanager.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QtGui/QHBoxLayout>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QApplication>
|
||||
|
||||
using namespace Core;
|
||||
using namespace Core::Internal;
|
||||
|
||||
EditorSplitter::EditorSplitter(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_curGroup(0)
|
||||
{
|
||||
registerActions();
|
||||
createRootGroup();
|
||||
updateActions();
|
||||
}
|
||||
|
||||
EditorSplitter::~EditorSplitter()
|
||||
{
|
||||
}
|
||||
|
||||
void EditorSplitter::registerActions()
|
||||
{
|
||||
QList<int> gc = QList<int>() << Constants::C_GLOBAL_ID;
|
||||
const QList<int> editorManagerContext =
|
||||
QList<int>() << ICore::instance()->uniqueIDManager()->uniqueIdentifier(Constants::C_EDITORMANAGER);
|
||||
|
||||
ActionManager *am = ICore::instance()->actionManager();
|
||||
ActionContainer *mwindow = am->actionContainer(Constants::M_WINDOW);
|
||||
Command *cmd;
|
||||
|
||||
#if 0
|
||||
//Horizontal Action
|
||||
m_horizontalSplitAction = new QAction(tr("Split Left/Right"), this);
|
||||
cmd = am->registerAction(m_horizontalSplitAction, Constants::HORIZONTAL, editorManagerContext);
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
connect(m_horizontalSplitAction, SIGNAL(triggered()),
|
||||
this, SLOT(splitHorizontal()));
|
||||
|
||||
//Vertical Action
|
||||
m_verticalSplitAction = new QAction(tr("Split Top/Bottom"), this);
|
||||
cmd = am->registerAction(m_verticalSplitAction, Constants::VERTICAL, editorManagerContext);
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
connect(m_verticalSplitAction, SIGNAL(triggered()),
|
||||
this, SLOT(splitVertical()));
|
||||
|
||||
//Unsplit Action
|
||||
m_unsplitAction = new QAction(tr("Unsplit"), this);
|
||||
cmd = am->registerAction(m_unsplitAction, Constants::REMOVE, editorManagerContext);
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
connect(m_unsplitAction, SIGNAL(triggered()),
|
||||
this, SLOT(unsplit()));
|
||||
|
||||
#endif
|
||||
|
||||
//Default Layout menu
|
||||
ActionContainer *mLayout = am->createMenu("QtCreator.Menu.Window.Layout");
|
||||
mwindow->addMenu(mLayout, Constants::G_WINDOW_SPLIT);
|
||||
mLayout->menu()->setTitle(tr("Default Splitter Layout"));
|
||||
|
||||
//Set Current As Default
|
||||
m_currentAsDefault = new QAction(tr("Save Current as Default"), this);
|
||||
cmd = am->registerAction(m_currentAsDefault, Constants::SAVEASDEFAULT, editorManagerContext);
|
||||
mLayout->addAction(cmd);
|
||||
connect(m_currentAsDefault, SIGNAL(triggered()),
|
||||
this, SLOT(saveCurrentLayout()));
|
||||
|
||||
//Restore Default
|
||||
m_restoreDefault = new QAction(tr("Restore Default Layout"), this);
|
||||
cmd = am->registerAction(m_restoreDefault, Constants::RESTOREDEFAULT, editorManagerContext);
|
||||
mLayout->addAction(cmd);
|
||||
connect(m_restoreDefault, SIGNAL(triggered()),
|
||||
this, SLOT(restoreDefaultLayout()));
|
||||
|
||||
// TODO: The previous and next actions are removed, to be reenabled when they
|
||||
// navigate according to code navigation history. And they need different shortcuts on the mac
|
||||
// since Alt+Left/Right is jumping wordwise in editors
|
||||
#if 0
|
||||
// Goto Previous Action
|
||||
m_gotoPreviousEditorAction = new QAction(QIcon(Constants::ICON_PREV), tr("Previous Document"), this);
|
||||
cmd = am->registerAction(m_gotoPreviousEditorAction, Constants::GOTOPREV, editorManagerContext);
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Left")));
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE);
|
||||
connect(m_gotoPreviousEditorAction, SIGNAL(triggered()), this, SLOT(gotoPreviousEditor()));
|
||||
|
||||
// Goto Next Action
|
||||
m_gotoNextEditorAction = new QAction(QIcon(Constants::ICON_NEXT), tr("Next Document"), this);
|
||||
cmd = am->registerAction(m_gotoNextEditorAction, Constants::GOTONEXT, editorManagerContext);
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Right")));
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE);
|
||||
connect(m_gotoNextEditorAction, SIGNAL(triggered()), this, SLOT(gotoNextEditor()));
|
||||
#endif
|
||||
|
||||
// Previous Group Action
|
||||
m_gotoPreviousGroupAction = new QAction(tr("Previous Group"), this);
|
||||
cmd = am->registerAction(m_gotoPreviousGroupAction, Constants::GOTOPREVIOUSGROUP, editorManagerContext);
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE_GROUPS);
|
||||
connect(m_gotoPreviousGroupAction, SIGNAL(triggered()), this, SLOT(selectPreviousGroup()));
|
||||
|
||||
// Next Group Action
|
||||
m_gotoNextGroupAction = new QAction(tr("Next Group"), this);
|
||||
cmd = am->registerAction(m_gotoNextGroupAction, Constants::GOTONEXTGROUP, editorManagerContext);
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE_GROUPS);
|
||||
connect(m_gotoNextGroupAction, SIGNAL(triggered()), this, SLOT(selectNextGroup()));
|
||||
|
||||
// Move to Previous Group
|
||||
m_moveDocToPreviousGroupAction = new QAction(tr("Move Document to Previous Group"), this);
|
||||
cmd = am->registerAction(m_moveDocToPreviousGroupAction, "QtCreator.DocumentToPreviousGroup", editorManagerContext);
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE_GROUPS);
|
||||
connect(m_moveDocToPreviousGroupAction, SIGNAL(triggered()), this, SLOT(moveDocToPreviousGroup()));
|
||||
|
||||
// Move to Next Group
|
||||
m_moveDocToNextGroupAction = new QAction(tr("Move Document to Next Group"), this);
|
||||
cmd = am->registerAction(m_moveDocToNextGroupAction, "QtCreator.DocumentToNextGroup", editorManagerContext);
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE_GROUPS);
|
||||
connect(m_moveDocToNextGroupAction, SIGNAL(triggered()), this, SLOT(moveDocToNextGroup()));
|
||||
}
|
||||
|
||||
void EditorSplitter::updateActions()
|
||||
{
|
||||
const bool hasMultipleGroups = (qobject_cast<QSplitter*>(m_root) != 0);
|
||||
QTC_ASSERT(currentGroup(), return);
|
||||
const bool hasEditors = (currentGroup()->editorCount() != 0);
|
||||
m_unsplitAction->setEnabled(hasMultipleGroups);
|
||||
#if 0
|
||||
const bool hasMultipleEditors = (editorCount() > 1);
|
||||
m_gotoNextEditorAction->setEnabled(hasMultipleEditors);
|
||||
m_gotoPreviousEditorAction->setEnabled(hasMultipleEditors);
|
||||
#endif
|
||||
m_gotoPreviousGroupAction->setEnabled(hasMultipleGroups);
|
||||
m_gotoNextGroupAction->setEnabled(hasMultipleGroups);
|
||||
m_moveDocToPreviousGroupAction->setEnabled(hasEditors && hasMultipleGroups);
|
||||
m_moveDocToNextGroupAction->setEnabled(hasEditors && hasMultipleGroups);
|
||||
}
|
||||
|
||||
int EditorSplitter::editorCount() const
|
||||
{
|
||||
int count = 0;
|
||||
foreach (EditorGroup *group, groups()) {
|
||||
count += group->editorCount();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void EditorSplitter::createRootGroup()
|
||||
{
|
||||
QHBoxLayout *l = new QHBoxLayout(this);
|
||||
l->setMargin(0);
|
||||
l->setSpacing(0);
|
||||
EditorGroup *rootGroup = createGroup();
|
||||
m_root = rootGroup->widget();
|
||||
l->addWidget(m_root);
|
||||
setCurrentGroup(rootGroup);
|
||||
}
|
||||
|
||||
void EditorSplitter::splitHorizontal()
|
||||
{
|
||||
split(Qt::Horizontal);
|
||||
}
|
||||
|
||||
void EditorSplitter::splitVertical()
|
||||
{
|
||||
split(Qt::Vertical);
|
||||
}
|
||||
|
||||
void EditorSplitter::gotoNextEditor()
|
||||
{
|
||||
OpenEditorsWindow *dialog = EditorManager::instance()->windowPopup();
|
||||
dialog->setMode(OpenEditorsWindow::ListMode);
|
||||
dialog->selectNextEditor();
|
||||
EditorManager::instance()->showWindowPopup();
|
||||
}
|
||||
|
||||
void EditorSplitter::gotoPreviousEditor()
|
||||
{
|
||||
OpenEditorsWindow *dialog = EditorManager::instance()->windowPopup();
|
||||
dialog->setMode(OpenEditorsWindow::ListMode);
|
||||
dialog->selectPreviousEditor();
|
||||
EditorManager::instance()->showWindowPopup();
|
||||
}
|
||||
|
||||
void EditorSplitter::setCurrentGroup(EditorGroup *group)
|
||||
{
|
||||
if (!group || group == m_curGroup)
|
||||
return;
|
||||
m_curGroup = group;
|
||||
if (m_curGroup->widget()->focusWidget() != QApplication::focusWidget())
|
||||
m_curGroup->widget()->setFocus();
|
||||
updateActions();
|
||||
}
|
||||
|
||||
QList<EditorGroup*> EditorSplitter::groups() const
|
||||
{
|
||||
QList<EditorGroup*> grps;
|
||||
collectGroups(m_root, grps);
|
||||
return grps;
|
||||
}
|
||||
|
||||
void EditorSplitter::collectGroups(QWidget *widget, QList<EditorGroup*> &groups) const
|
||||
{
|
||||
EditorGroup *group = qobject_cast<EditorGroup *>(widget);
|
||||
if (group) {
|
||||
groups += group;
|
||||
return;
|
||||
}
|
||||
QSplitter *splitter = qobject_cast<QSplitter*>(widget);
|
||||
QTC_ASSERT(splitter, return);
|
||||
collectGroups(splitter->widget(LEFT), groups);
|
||||
collectGroups(splitter->widget(RIGHT), groups);
|
||||
}
|
||||
|
||||
|
||||
EditorGroup *EditorSplitter::currentGroup() const
|
||||
{
|
||||
return m_curGroup;
|
||||
}
|
||||
|
||||
void EditorSplitter::split(Qt::Orientation orientation)
|
||||
{
|
||||
EditorGroup *curGroup = currentGroup();
|
||||
IEditor *editor = curGroup->currentEditor();
|
||||
split(orientation, 0);
|
||||
if (editor) {
|
||||
EditorGroup *otherGroup = currentGroup();
|
||||
if (curGroup != otherGroup) {
|
||||
curGroup->removeEditor(editor);
|
||||
otherGroup->addEditor(editor);
|
||||
}
|
||||
}
|
||||
emit editorGroupsChanged();
|
||||
}
|
||||
|
||||
QSplitter *EditorSplitter::split(Qt::Orientation orientation, EditorGroup *group)
|
||||
{
|
||||
EditorGroup *curGroup = group;
|
||||
if (!curGroup)
|
||||
curGroup = currentGroup();
|
||||
if (!curGroup)
|
||||
return 0;
|
||||
|
||||
int oldSibling1 = -1;
|
||||
int oldSibling2 = -1;
|
||||
int idx = 1;
|
||||
QWidget *curGroupWidget = curGroup->widget();
|
||||
QSplitter *parentSplitter = qobject_cast<QSplitter*>(curGroupWidget->parentWidget());
|
||||
if (parentSplitter) {
|
||||
if (parentSplitter->orientation() == Qt::Vertical) {
|
||||
oldSibling1 = parentSplitter->widget(LEFT)->height();
|
||||
oldSibling2 = parentSplitter->widget(RIGHT)->height();
|
||||
} else {
|
||||
oldSibling1 = parentSplitter->widget(LEFT)->width();
|
||||
oldSibling2 = parentSplitter->widget(RIGHT)->width();
|
||||
}
|
||||
idx = parentSplitter->indexOf(curGroupWidget);
|
||||
}
|
||||
|
||||
QLayout *l = curGroupWidget->parentWidget()->layout();
|
||||
curGroupWidget->setParent(0);
|
||||
|
||||
QSplitter *splitter = new MiniSplitter(0);
|
||||
splitter->setOrientation(orientation);
|
||||
EditorGroup *eg = createGroup();
|
||||
|
||||
splitter->addWidget(curGroupWidget);
|
||||
splitter->addWidget(eg->widget());
|
||||
|
||||
if (curGroupWidget == m_root) {
|
||||
l->addWidget(splitter);
|
||||
m_root = splitter;
|
||||
} else {
|
||||
parentSplitter->insertWidget(idx, splitter);
|
||||
}
|
||||
|
||||
if (parentSplitter)
|
||||
parentSplitter->setSizes(QList<int>() << oldSibling1 << oldSibling2);
|
||||
if (orientation == Qt::Vertical)
|
||||
splitter->setSizes(QList<int>() << curGroupWidget->height()/2
|
||||
<< curGroupWidget->height()/2);
|
||||
else
|
||||
splitter->setSizes(QList<int>() << curGroupWidget->width()/2
|
||||
<< curGroupWidget->width()/2);
|
||||
setCurrentGroup(eg);
|
||||
return splitter;
|
||||
}
|
||||
|
||||
void EditorSplitter::unsplit()
|
||||
{
|
||||
EditorGroup *curGroup = currentGroup();
|
||||
if (!curGroup)
|
||||
return;
|
||||
QWidget *curGroupWidget = curGroup->widget();
|
||||
QTC_ASSERT(curGroupWidget, return);
|
||||
IEditor *selectedEditor = curGroup->currentEditor();
|
||||
|
||||
QSplitter *parentSplitter = qobject_cast<QSplitter*>(curGroupWidget->parentWidget());
|
||||
if (parentSplitter) {
|
||||
int oldSibling1 = -1;
|
||||
int oldSibling2 = -1;
|
||||
|
||||
EditorGroup *e1 = qobject_cast<EditorGroup *>(parentSplitter->widget(LEFT));
|
||||
EditorGroup *e2 = qobject_cast<EditorGroup *>(parentSplitter->widget(RIGHT));
|
||||
|
||||
QWidget *w = parentSplitter->parentWidget();
|
||||
QSplitter *grandParentSplitter = qobject_cast<QSplitter*>(w);
|
||||
int idx = 0;
|
||||
if (grandParentSplitter) {
|
||||
idx = grandParentSplitter->indexOf(parentSplitter);
|
||||
if (grandParentSplitter->orientation() == Qt::Vertical) {
|
||||
oldSibling1 = grandParentSplitter->widget(LEFT)->height();
|
||||
oldSibling2 = grandParentSplitter->widget(RIGHT)->height();
|
||||
} else {
|
||||
oldSibling1 = grandParentSplitter->widget(LEFT)->width();
|
||||
oldSibling2 = grandParentSplitter->widget(RIGHT)->width();
|
||||
}
|
||||
}
|
||||
if (e1 && e2) { // we are unsplitting a split that contains of groups directly not one or more additional splits
|
||||
e1->moveEditorsFromGroup(e2);
|
||||
parentSplitter->setParent(0);
|
||||
if (grandParentSplitter) {
|
||||
grandParentSplitter->insertWidget(idx, e1->widget());
|
||||
} else {
|
||||
w->layout()->addWidget(e1->widget());
|
||||
m_root = e1->widget();
|
||||
}
|
||||
setCurrentGroup(e1);
|
||||
deleteGroup(e2);
|
||||
e2 = 0;
|
||||
delete parentSplitter;
|
||||
e1->setCurrentEditor(selectedEditor);
|
||||
} else if (e1 || e2) {
|
||||
parentSplitter->setParent(0);
|
||||
QSplitter *s = 0;
|
||||
if (e1) {
|
||||
s = qobject_cast<QSplitter*>(parentSplitter->widget(RIGHT));
|
||||
} else {
|
||||
s = qobject_cast<QSplitter*>(parentSplitter->widget(LEFT));
|
||||
e1 = e2;
|
||||
}
|
||||
|
||||
if (grandParentSplitter) {
|
||||
grandParentSplitter->insertWidget(idx, s);
|
||||
} else {
|
||||
w->layout()->addWidget(s);
|
||||
m_root = s;
|
||||
}
|
||||
EditorGroup *leftMost = groupFarthestOnSide(s, LEFT);
|
||||
leftMost->moveEditorsFromGroup(e1);
|
||||
leftMost->setCurrentEditor(selectedEditor);
|
||||
setCurrentGroup(leftMost);
|
||||
deleteGroup(e1);
|
||||
}
|
||||
if (grandParentSplitter)
|
||||
grandParentSplitter->setSizes(QList<int>() << oldSibling1 << oldSibling2);
|
||||
emit editorGroupsChanged();
|
||||
}
|
||||
updateActions();
|
||||
}
|
||||
|
||||
void EditorSplitter::unsplitAll()
|
||||
{
|
||||
QSplitter *rootSplit = qobject_cast<QSplitter *>(m_root);
|
||||
if (!rootSplit)
|
||||
return;
|
||||
// first create and set the new root, then kill the original stuff
|
||||
// this way we can avoid unnecessary signals/ context changes
|
||||
rootSplit->setParent(0);
|
||||
EditorGroup *rootGroup = createGroup();
|
||||
QLayout *l = layout();
|
||||
l->addWidget(rootGroup->widget());
|
||||
m_root = rootGroup->widget();
|
||||
setCurrentGroup(rootGroup);
|
||||
// kill old hierarchy
|
||||
QList<IEditor *> editors;
|
||||
unsplitAll(rootSplit->widget(1), editors);
|
||||
unsplitAll(rootSplit->widget(0), editors);
|
||||
delete rootSplit;
|
||||
rootSplit = 0;
|
||||
foreach (IEditor *editor, editors) {
|
||||
rootGroup->addEditor(editor);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorSplitter::unsplitAll(QWidget *node, QList<IEditor*> &editors)
|
||||
{
|
||||
QSplitter *splitter = qobject_cast<QSplitter *>(node);
|
||||
if (splitter) {
|
||||
unsplitAll(splitter->widget(1), editors);
|
||||
unsplitAll(splitter->widget(0), editors);
|
||||
delete splitter;
|
||||
splitter = 0;
|
||||
} else {
|
||||
EditorGroup *group = qobject_cast<EditorGroup *>(node);
|
||||
editors << group->editors();
|
||||
bool blocking = group->widget()->blockSignals(true);
|
||||
foreach (IEditor *editor, group->editors()) {
|
||||
group->removeEditor(editor);
|
||||
}
|
||||
group->widget()->blockSignals(blocking);
|
||||
deleteGroup(group);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGroup *EditorSplitter::groupFarthestOnSide(QWidget *node, Side side) const
|
||||
{
|
||||
QWidget *current = node;
|
||||
QSplitter *split = 0;
|
||||
while ((split = qobject_cast<QSplitter*>(current))) {
|
||||
current = split->widget(side);
|
||||
}
|
||||
return qobject_cast<EditorGroup *>(current);
|
||||
}
|
||||
|
||||
void EditorSplitter::selectNextGroup()
|
||||
{
|
||||
EditorGroup *curGroup = currentGroup();
|
||||
QTC_ASSERT(curGroup, return);
|
||||
setCurrentGroup(nextGroup(curGroup, RIGHT));
|
||||
}
|
||||
|
||||
void EditorSplitter::selectPreviousGroup()
|
||||
{
|
||||
EditorGroup *curGroup = currentGroup();
|
||||
QTC_ASSERT(curGroup, return);
|
||||
setCurrentGroup(nextGroup(curGroup, LEFT));
|
||||
}
|
||||
|
||||
EditorGroup *EditorSplitter::nextGroup(EditorGroup *curGroup, Side side) const
|
||||
{
|
||||
QTC_ASSERT(curGroup, return 0);
|
||||
QWidget *curWidget = curGroup->widget();
|
||||
QWidget *parent = curWidget->parentWidget();
|
||||
while (curWidget != m_root) {
|
||||
QSplitter *splitter = qobject_cast<QSplitter *>(parent);
|
||||
QTC_ASSERT(splitter, return 0);
|
||||
if (splitter->widget(side) != curWidget) {
|
||||
curWidget = splitter->widget(side);
|
||||
break;
|
||||
}
|
||||
curWidget = parent;
|
||||
parent = curWidget->parentWidget();
|
||||
}
|
||||
return groupFarthestOnSide(curWidget, side==LEFT ? RIGHT : LEFT);
|
||||
}
|
||||
|
||||
void EditorSplitter::moveDocToAdjacentGroup(Side side)
|
||||
{
|
||||
EditorGroup *curGroup = currentGroup();
|
||||
QTC_ASSERT(curGroup, return);
|
||||
IEditor *editor = curGroup->currentEditor();
|
||||
if (!editor)
|
||||
return;
|
||||
EditorGroup *next = nextGroup(curGroup, side);
|
||||
next->moveEditorFromGroup(curGroup, editor);
|
||||
setCurrentGroup(next);
|
||||
}
|
||||
|
||||
void EditorSplitter::moveDocToNextGroup()
|
||||
{
|
||||
moveDocToAdjacentGroup(RIGHT);
|
||||
}
|
||||
|
||||
void EditorSplitter::moveDocToPreviousGroup()
|
||||
{
|
||||
moveDocToAdjacentGroup(LEFT);
|
||||
}
|
||||
|
||||
QWidget *EditorSplitter::recreateGroupTree(QWidget *node)
|
||||
{
|
||||
QSplitter *splitter = qobject_cast<QSplitter *>(node);
|
||||
if (!splitter) {
|
||||
EditorGroup *group = qobject_cast<EditorGroup *>(node);
|
||||
QTC_ASSERT(group, return 0);
|
||||
IEditor *currentEditor = group->currentEditor();
|
||||
EditorGroup *newGroup = createGroup();
|
||||
bool block = newGroup->widget()->blockSignals(true);
|
||||
foreach (IEditor *editor, group->editors()) {
|
||||
newGroup->addEditor(editor);
|
||||
}
|
||||
newGroup->setCurrentEditor(currentEditor);
|
||||
deleteGroup(group);
|
||||
newGroup->widget()->blockSignals(block);
|
||||
return newGroup->widget();
|
||||
} else {
|
||||
QByteArray splitterState = splitter->saveState();
|
||||
QWidget *orig0 = splitter->widget(0);
|
||||
QWidget *orig1 = splitter->widget(1);
|
||||
QWidget *g0 = recreateGroupTree(orig0);
|
||||
QWidget *g1 = recreateGroupTree(orig1);
|
||||
splitter->insertWidget(0, g0);
|
||||
splitter->insertWidget(1, g1);
|
||||
splitter->restoreState(splitterState);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
void EditorSplitter::saveCurrentLayout()
|
||||
{
|
||||
QSettings *settings = ICore::instance()->settings();
|
||||
settings->setValue("EditorManager/Splitting", saveState());
|
||||
}
|
||||
|
||||
void EditorSplitter::restoreDefaultLayout()
|
||||
{
|
||||
QSettings *settings = ICore::instance()->settings();
|
||||
if (settings->contains("EditorManager/Splitting"))
|
||||
restoreState(settings->value("EditorManager/Splitting").toByteArray());
|
||||
}
|
||||
|
||||
void EditorSplitter::saveSettings(QSettings * /*settings*/) const
|
||||
{
|
||||
}
|
||||
|
||||
void EditorSplitter::readSettings(QSettings * /*settings*/)
|
||||
{
|
||||
restoreDefaultLayout();
|
||||
}
|
||||
|
||||
QByteArray EditorSplitter::saveState() const
|
||||
{
|
||||
//todo: versioning
|
||||
QByteArray bytes;
|
||||
QDataStream stream(&bytes, QIODevice::WriteOnly);
|
||||
saveState(m_root, stream);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
bool EditorSplitter::restoreState(const QByteArray &state)
|
||||
{
|
||||
unsplitAll();
|
||||
//todo: versioning
|
||||
QDataStream stream(state);
|
||||
EditorGroup *curGroup =
|
||||
restoreState(qobject_cast<EditorGroup *>(m_root), stream);
|
||||
setCurrentGroup(curGroup);
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditorSplitter::saveState(QWidget *current, QDataStream &stream) const
|
||||
{
|
||||
QSplitter *splitter = qobject_cast<QSplitter *>(current);
|
||||
quint8 type;
|
||||
if (splitter) {
|
||||
type = 0;
|
||||
stream << type;
|
||||
stream << splitter->saveState();
|
||||
saveState(splitter->widget(0), stream);
|
||||
saveState(splitter->widget(1), stream);
|
||||
} else {
|
||||
EditorGroup *group = qobject_cast<EditorGroup *>(current);
|
||||
QTC_ASSERT(group, /**/);
|
||||
if (group != currentGroup())
|
||||
type = 1;
|
||||
else
|
||||
type = 2;
|
||||
stream << type;
|
||||
}
|
||||
}
|
||||
|
||||
EditorGroup *EditorSplitter::restoreState(EditorGroup *current,
|
||||
QDataStream &stream)
|
||||
{
|
||||
EditorGroup *curGroup = 0;
|
||||
EditorGroup *group;
|
||||
quint8 type;
|
||||
stream >> type;
|
||||
if (type == 0) {
|
||||
QSplitter *splitter = split(Qt::Horizontal, current);
|
||||
QByteArray splitterState;
|
||||
stream >> splitterState;
|
||||
splitter->restoreState(splitterState);
|
||||
group = restoreState(qobject_cast<EditorGroup *>(splitter->widget(0)),
|
||||
stream);
|
||||
if (group)
|
||||
curGroup = group;
|
||||
group = restoreState(qobject_cast<EditorGroup *>(splitter->widget(1)),
|
||||
stream);
|
||||
if (group)
|
||||
curGroup = group;
|
||||
} else {
|
||||
if (type == 2)
|
||||
return current;
|
||||
}
|
||||
return curGroup;
|
||||
}
|
||||
|
||||
QMap<QString,EditorGroup *> EditorSplitter::pathGroupMap()
|
||||
{
|
||||
QMap<QString,EditorGroup *> map;
|
||||
fillPathGroupMap(m_root, "", map);
|
||||
return map;
|
||||
}
|
||||
|
||||
void EditorSplitter::fillPathGroupMap(QWidget *current, QString currentPath,
|
||||
QMap<QString,EditorGroup *> &map)
|
||||
{
|
||||
EditorGroup *group = qobject_cast<EditorGroup *>(current);
|
||||
if (group) {
|
||||
map.insert(currentPath, group);
|
||||
} else {
|
||||
QSplitter *splitter = qobject_cast<QSplitter *>(current);
|
||||
QTC_ASSERT(splitter, return);
|
||||
fillPathGroupMap(splitter->widget(0), currentPath+"0", map);
|
||||
fillPathGroupMap(splitter->widget(1), currentPath+"1", map);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGroup *EditorSplitter::createGroup()
|
||||
{
|
||||
EditorGroup *group = new StackedEditorGroup(this);
|
||||
connect(group, SIGNAL(closeRequested(Core::IEditor *)),
|
||||
this, SIGNAL(closeRequested(Core::IEditor *)));
|
||||
connect(group, SIGNAL(editorRemoved(Core::IEditor *)),
|
||||
this, SLOT(updateActions()));
|
||||
connect(group, SIGNAL(editorAdded(Core::IEditor *)),
|
||||
this, SLOT(updateActions()));
|
||||
ICore::instance()->addContextObject(group->contextObject());
|
||||
return group;
|
||||
}
|
||||
|
||||
void EditorSplitter::deleteGroup(EditorGroup *group)
|
||||
{
|
||||
ICore::instance()->removeContextObject(group->contextObject());
|
||||
delete group;
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef EDITORSPLITTER_H
|
||||
#define EDITORSPLITTER_H
|
||||
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QSplitter>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class EditorGroup;
|
||||
class IEditor;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class EditorSplitter : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EditorSplitter(QWidget *parent = 0);
|
||||
~EditorSplitter();
|
||||
|
||||
void setCurrentGroup(Core::EditorGroup *group);
|
||||
EditorGroup *currentGroup() const;
|
||||
QList<EditorGroup*> groups() const;
|
||||
|
||||
void split(Qt::Orientation orientation);
|
||||
|
||||
void saveSettings(QSettings *settings) const;
|
||||
void readSettings(QSettings *settings);
|
||||
QByteArray saveState() const;
|
||||
bool restoreState(const QByteArray &state);
|
||||
|
||||
QMap<QString,EditorGroup *> pathGroupMap();
|
||||
|
||||
public slots:
|
||||
void unsplit();
|
||||
|
||||
signals:
|
||||
void closeRequested(Core::IEditor *editor);
|
||||
void editorGroupsChanged();
|
||||
|
||||
private slots:
|
||||
void splitHorizontal();
|
||||
void splitVertical();
|
||||
void gotoNextEditor();
|
||||
void gotoPreviousEditor();
|
||||
void updateActions();
|
||||
void selectNextGroup();
|
||||
void selectPreviousGroup();
|
||||
void moveDocToNextGroup();
|
||||
void moveDocToPreviousGroup();
|
||||
void saveCurrentLayout();
|
||||
void restoreDefaultLayout();
|
||||
|
||||
private:
|
||||
enum Side {LEFT = 0, RIGHT = 1};
|
||||
|
||||
void registerActions();
|
||||
void createRootGroup();
|
||||
EditorGroup *createGroup();
|
||||
void deleteGroup(EditorGroup *group);
|
||||
void collectGroups(QWidget *widget, QList<EditorGroup*> &groups) const;
|
||||
EditorGroup *groupFarthestOnSide(QWidget *node, Side side) const;
|
||||
EditorGroup *nextGroup(EditorGroup *curGroup, Side side) const;
|
||||
void moveDocToAdjacentGroup(Side side);
|
||||
void saveState(QWidget *current, QDataStream &stream) const;
|
||||
EditorGroup *restoreState(EditorGroup *current, QDataStream &stream);
|
||||
QSplitter *split(Qt::Orientation orientation, EditorGroup *group);
|
||||
void fillPathGroupMap(QWidget *current, QString currentPath,
|
||||
QMap<QString,EditorGroup *> &map);
|
||||
void unsplitAll();
|
||||
void unsplitAll(QWidget *node, QList<IEditor *> &editors);
|
||||
QWidget *recreateGroupTree(QWidget *node);
|
||||
int editorCount() const;
|
||||
|
||||
QWidget *m_root;
|
||||
EditorGroup *m_curGroup;
|
||||
|
||||
QAction *m_horizontalSplitAction;
|
||||
QAction *m_verticalSplitAction;
|
||||
QAction *m_unsplitAction;
|
||||
#if 0
|
||||
QAction *m_gotoNextEditorAction;
|
||||
QAction *m_gotoPreviousEditorAction;
|
||||
#endif
|
||||
QAction *m_gotoNextGroupAction;
|
||||
QAction *m_gotoPreviousGroupAction;
|
||||
QAction *m_moveDocToNextGroupAction;
|
||||
QAction *m_moveDocToPreviousGroupAction;
|
||||
QAction *m_currentAsDefault;
|
||||
QAction *m_restoreDefault;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
#endif // EDITORSPLITTER_H
|
@ -1,1012 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "editorview.h"
|
||||
#include "editormanager.h"
|
||||
#include "coreimpl.h"
|
||||
#include "minisplitter.h"
|
||||
#include "openeditorsmodel.h"
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
|
||||
#include <coreplugin/findplaceholder.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/styledbar.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QMimeData>
|
||||
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QComboBox>
|
||||
#include <QtGui/QHBoxLayout>
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtGui/QMouseEvent>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QStackedWidget>
|
||||
#include <QtGui/QStyle>
|
||||
#include <QtGui/QStyleOption>
|
||||
#include <QtGui/QToolButton>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QClipboard>
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
#include <qmacstyle_mac.h>
|
||||
#endif
|
||||
|
||||
Q_DECLARE_METATYPE(Core::IEditor *)
|
||||
|
||||
using namespace Core;
|
||||
using namespace Core::Internal;
|
||||
|
||||
|
||||
// ================EditorView====================
|
||||
|
||||
EditorView::EditorView(OpenEditorsModel *model, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
m_model(model),
|
||||
m_toolBar(new QWidget),
|
||||
m_container(new QStackedWidget(this)),
|
||||
m_editorList(new QComboBox),
|
||||
m_closeButton(new QToolButton),
|
||||
m_lockButton(new QToolButton),
|
||||
m_defaultToolBar(new QWidget(this)),
|
||||
m_infoWidget(new QFrame(this)),
|
||||
m_editorForInfoWidget(0),
|
||||
m_statusHLine(new QFrame(this)),
|
||||
m_statusWidget(new QFrame(this)),
|
||||
m_currentNavigationHistoryPosition(0)
|
||||
{
|
||||
|
||||
m_goBackAction = new QAction(QIcon(QLatin1String(":/help/images/previous.png")), tr("Go Back"), this);
|
||||
connect(m_goBackAction, SIGNAL(triggered()), this, SLOT(goBackInNavigationHistory()));
|
||||
m_goForwardAction = new QAction(QIcon(QLatin1String(":/help/images/next.png")), tr("Go Forward"), this);
|
||||
connect(m_goForwardAction, SIGNAL(triggered()), this, SLOT(goForwardInNavigationHistory()));
|
||||
|
||||
QVBoxLayout *tl = new QVBoxLayout(this);
|
||||
tl->setSpacing(0);
|
||||
tl->setMargin(0);
|
||||
{
|
||||
if (!m_model) {
|
||||
m_model = CoreImpl::instance()->editorManager()->openedEditorsModel();
|
||||
}
|
||||
|
||||
QToolButton *backButton = new QToolButton;
|
||||
backButton->setDefaultAction(m_goBackAction);
|
||||
|
||||
QToolButton *forwardButton= new QToolButton;
|
||||
forwardButton->setDefaultAction(m_goForwardAction);
|
||||
|
||||
m_editorList->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
m_editorList->setMinimumContentsLength(20);
|
||||
m_editorList->setModel(m_model);
|
||||
m_editorList->setMaxVisibleItems(40);
|
||||
m_editorList->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
m_defaultToolBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
m_activeToolBar = m_defaultToolBar;
|
||||
|
||||
QHBoxLayout *toolBarLayout = new QHBoxLayout;
|
||||
toolBarLayout->setMargin(0);
|
||||
toolBarLayout->setSpacing(0);
|
||||
toolBarLayout->addWidget(m_defaultToolBar);
|
||||
m_toolBar->setLayout(toolBarLayout);
|
||||
m_toolBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
|
||||
m_lockButton->setAutoRaise(true);
|
||||
|
||||
m_closeButton->setAutoRaise(true);
|
||||
m_closeButton->setIcon(QIcon(":/core/images/closebutton.png"));
|
||||
|
||||
|
||||
QHBoxLayout *toplayout = new QHBoxLayout;
|
||||
toplayout->setSpacing(0);
|
||||
toplayout->setMargin(0);
|
||||
toplayout->addWidget(backButton);
|
||||
toplayout->addWidget(forwardButton);
|
||||
toplayout->addWidget(m_editorList);
|
||||
toplayout->addWidget(m_toolBar, 1); // Custom toolbar stretches
|
||||
toplayout->addWidget(m_lockButton);
|
||||
toplayout->addWidget(m_closeButton);
|
||||
|
||||
Utils::StyledBar *top = new Utils::StyledBar;
|
||||
top->setLayout(toplayout);
|
||||
tl->addWidget(top);
|
||||
|
||||
connect(m_editorList, SIGNAL(activated(int)), this, SLOT(listSelectionActivated(int)));
|
||||
connect(m_editorList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(listContextMenu(QPoint)));
|
||||
connect(m_lockButton, SIGNAL(clicked()), this, SLOT(makeEditorWritable()));
|
||||
connect(m_closeButton, SIGNAL(clicked()), this, SLOT(closeView()), Qt::QueuedConnection);
|
||||
}
|
||||
{
|
||||
m_infoWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
|
||||
m_infoWidget->setLineWidth(1);
|
||||
m_infoWidget->setForegroundRole(QPalette::ToolTipText);
|
||||
m_infoWidget->setBackgroundRole(QPalette::ToolTipBase);
|
||||
m_infoWidget->setAutoFillBackground(true);
|
||||
|
||||
QHBoxLayout *hbox = new QHBoxLayout(m_infoWidget);
|
||||
hbox->setMargin(2);
|
||||
m_infoWidgetLabel = new QLabel("Placeholder");
|
||||
m_infoWidgetLabel->setForegroundRole(QPalette::ToolTipText);
|
||||
hbox->addWidget(m_infoWidgetLabel);
|
||||
hbox->addStretch(1);
|
||||
|
||||
m_infoWidgetButton = new QToolButton;
|
||||
m_infoWidgetButton->setText(tr("Placeholder"));
|
||||
hbox->addWidget(m_infoWidgetButton);
|
||||
|
||||
QToolButton *closeButton = new QToolButton;
|
||||
closeButton->setAutoRaise(true);
|
||||
closeButton->setIcon(QIcon(":/core/images/clear.png"));
|
||||
closeButton->setToolTip(tr("Close"));
|
||||
connect(closeButton, SIGNAL(clicked()), m_infoWidget, SLOT(hide()));
|
||||
|
||||
hbox->addWidget(closeButton);
|
||||
|
||||
m_infoWidget->setVisible(false);
|
||||
tl->addWidget(m_infoWidget);
|
||||
}
|
||||
|
||||
tl->addWidget(m_container);
|
||||
|
||||
tl->addWidget(new FindToolBarPlaceHolder(this));
|
||||
|
||||
{
|
||||
m_statusHLine->setFrameStyle(QFrame::HLine);
|
||||
|
||||
m_statusWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
|
||||
m_statusWidget->setLineWidth(1);
|
||||
//m_statusWidget->setForegroundRole(QPalette::ToolTipText);
|
||||
//m_statusWidget->setBackgroundRole(QPalette::ToolTipBase);
|
||||
m_statusWidget->setAutoFillBackground(true);
|
||||
|
||||
|
||||
QHBoxLayout *hbox = new QHBoxLayout(m_statusWidget);
|
||||
hbox->setMargin(2);
|
||||
m_statusWidgetLabel = new QLabel("Placeholder");
|
||||
m_statusWidgetLabel->setForegroundRole(QPalette::ToolTipText);
|
||||
hbox->addWidget(m_statusWidgetLabel);
|
||||
hbox->addStretch(1);
|
||||
|
||||
m_statusWidgetButton = new QToolButton;
|
||||
m_statusWidgetButton->setText(tr("Placeholder"));
|
||||
hbox->addWidget(m_statusWidgetButton);
|
||||
|
||||
m_statusHLine->setVisible(false);
|
||||
m_statusWidget->setVisible(false);
|
||||
tl->addWidget(m_statusHLine);
|
||||
tl->addWidget(m_statusWidget);
|
||||
}
|
||||
|
||||
|
||||
ActionManager *am = ICore::instance()->actionManager();
|
||||
connect(am->command(Constants::CLOSE), SIGNAL(keySequenceChanged()),
|
||||
this, SLOT(updateActionShortcuts()));
|
||||
connect(am->command(Constants::GO_BACK), SIGNAL(keySequenceChanged()),
|
||||
this, SLOT(updateActionShortcuts()));
|
||||
connect(am->command(Constants::GO_FORWARD), SIGNAL(keySequenceChanged()),
|
||||
this, SLOT(updateActionShortcuts()));
|
||||
|
||||
updateActionShortcuts();
|
||||
updateActions();
|
||||
}
|
||||
|
||||
EditorView::~EditorView()
|
||||
{
|
||||
}
|
||||
|
||||
void EditorView::showEditorInfoBar(const QString &kind,
|
||||
const QString &infoText,
|
||||
const QString &buttonText,
|
||||
QObject *object, const char *member)
|
||||
{
|
||||
m_infoWidgetKind = kind;
|
||||
m_infoWidgetLabel->setText(infoText);
|
||||
m_infoWidgetButton->setText(buttonText);
|
||||
m_infoWidgetButton->disconnect();
|
||||
if (object && member)
|
||||
connect(m_infoWidgetButton, SIGNAL(clicked()), object, member);
|
||||
m_infoWidget->setVisible(true);
|
||||
m_editorForInfoWidget = currentEditor();
|
||||
}
|
||||
|
||||
void EditorView::hideEditorInfoBar(const QString &kind)
|
||||
{
|
||||
if (kind == m_infoWidgetKind)
|
||||
m_infoWidget->setVisible(false);
|
||||
}
|
||||
|
||||
void EditorView::showEditorStatusBar(const QString &kind,
|
||||
const QString &infoText,
|
||||
const QString &buttonText,
|
||||
QObject *object, const char *member)
|
||||
{
|
||||
m_statusWidgetKind = kind;
|
||||
m_statusWidgetLabel->setText(infoText);
|
||||
m_statusWidgetButton->setText(buttonText);
|
||||
m_statusWidgetButton->disconnect();
|
||||
if (object && member)
|
||||
connect(m_statusWidgetButton, SIGNAL(clicked()), object, member);
|
||||
m_statusWidget->setVisible(true);
|
||||
m_statusHLine->setVisible(true);
|
||||
//m_editorForInfoWidget = currentEditor();
|
||||
}
|
||||
|
||||
void EditorView::hideEditorStatusBar(const QString &kind)
|
||||
{
|
||||
if (kind == m_statusWidgetKind) {
|
||||
m_statusWidget->setVisible(false);
|
||||
m_statusHLine->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorView::addEditor(IEditor *editor)
|
||||
{
|
||||
if (m_editors.contains(editor))
|
||||
return;
|
||||
|
||||
m_editors.append(editor);
|
||||
|
||||
m_container->addWidget(editor->widget());
|
||||
m_widgetEditorMap.insert(editor->widget(), editor);
|
||||
|
||||
QWidget *toolBar = editor->toolBar();
|
||||
if (toolBar) {
|
||||
toolBar->setVisible(false); // will be made visible in setCurrentEditor
|
||||
m_toolBar->layout()->addWidget(toolBar);
|
||||
}
|
||||
connect(editor, SIGNAL(changed()), this, SLOT(checkEditorStatus()));
|
||||
|
||||
if (editor == currentEditor())
|
||||
setCurrentEditor(editor);
|
||||
}
|
||||
|
||||
bool EditorView::hasEditor(IEditor *editor) const
|
||||
{
|
||||
return m_editors.contains(editor);
|
||||
}
|
||||
|
||||
void EditorView::closeView()
|
||||
{
|
||||
EditorManager *em = CoreImpl::instance()->editorManager();
|
||||
if (IEditor *editor = currentEditor()) {
|
||||
em->closeDuplicate(editor);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorView::removeEditor(IEditor *editor)
|
||||
{
|
||||
QTC_ASSERT(editor, return);
|
||||
if (!m_editors.contains(editor))
|
||||
return;
|
||||
|
||||
const int index = m_container->indexOf(editor->widget());
|
||||
QTC_ASSERT((index != -1), return);
|
||||
bool wasCurrent = (index == m_container->currentIndex());
|
||||
m_editors.removeAll(editor);
|
||||
|
||||
m_container->removeWidget(editor->widget());
|
||||
m_widgetEditorMap.remove(editor->widget());
|
||||
editor->widget()->setParent(0);
|
||||
disconnect(editor, SIGNAL(changed()), this, SLOT(checkEditorStatus()));
|
||||
QWidget *toolBar = editor->toolBar();
|
||||
if (toolBar != 0) {
|
||||
if (m_activeToolBar == toolBar) {
|
||||
m_activeToolBar = m_defaultToolBar;
|
||||
m_activeToolBar->setVisible(true);
|
||||
}
|
||||
m_toolBar->layout()->removeWidget(toolBar);
|
||||
toolBar->setVisible(false);
|
||||
toolBar->setParent(0);
|
||||
}
|
||||
if (wasCurrent)
|
||||
setCurrentEditor(m_editors.count() ? m_editors.last() : 0);
|
||||
}
|
||||
|
||||
IEditor *EditorView::currentEditor() const
|
||||
{
|
||||
if (m_container->count() > 0)
|
||||
return m_widgetEditorMap.value(m_container->currentWidget());
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EditorView::setCurrentEditor(IEditor *editor)
|
||||
{
|
||||
if (!editor || m_container->count() <= 0
|
||||
|| m_container->indexOf(editor->widget()) == -1) {
|
||||
updateEditorStatus(0);
|
||||
// ### TODO the combo box m_editorList should show an empty item
|
||||
return;
|
||||
}
|
||||
|
||||
m_editors.removeAll(editor);
|
||||
m_editors.append(editor);
|
||||
|
||||
const int idx = m_container->indexOf(editor->widget());
|
||||
QTC_ASSERT(idx >= 0, return);
|
||||
m_container->setCurrentIndex(idx);
|
||||
m_editorList->setCurrentIndex(m_model->indexOf(editor).row());
|
||||
updateEditorStatus(editor);
|
||||
updateToolBar(editor);
|
||||
updateEditorHistory(editor);
|
||||
|
||||
// FIXME: this keeps the editor hidden if switching from A to B and back
|
||||
if (editor != m_editorForInfoWidget) {
|
||||
m_infoWidget->hide();
|
||||
m_editorForInfoWidget = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void EditorView::checkEditorStatus()
|
||||
{
|
||||
IEditor *editor = qobject_cast<IEditor *>(sender());
|
||||
if (editor == currentEditor())
|
||||
updateEditorStatus(editor);
|
||||
}
|
||||
|
||||
void EditorView::updateEditorStatus(IEditor *editor)
|
||||
{
|
||||
static const QIcon lockedIcon(QLatin1String(":/core/images/locked.png"));
|
||||
static const QIcon unlockedIcon(QLatin1String(":/core/images/unlocked.png"));
|
||||
|
||||
m_lockButton->setVisible(editor != 0);
|
||||
|
||||
if (!editor) {
|
||||
m_editorList->setToolTip(QString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (editor->file()->isReadOnly()) {
|
||||
m_lockButton->setIcon(lockedIcon);
|
||||
m_lockButton->setEnabled(!editor->file()->fileName().isEmpty());
|
||||
m_lockButton->setToolTip(tr("Make writable"));
|
||||
} else {
|
||||
m_lockButton->setIcon(unlockedIcon);
|
||||
m_lockButton->setEnabled(false);
|
||||
m_lockButton->setToolTip(tr("File is writable"));
|
||||
}
|
||||
if (currentEditor() == editor)
|
||||
m_editorList->setToolTip(
|
||||
editor->file()->fileName().isEmpty()
|
||||
? editor->displayName()
|
||||
: QDir::toNativeSeparators(editor->file()->fileName())
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void EditorView::updateToolBar(IEditor *editor)
|
||||
{
|
||||
QWidget *toolBar = editor->toolBar();
|
||||
if (!toolBar)
|
||||
toolBar = m_defaultToolBar;
|
||||
if (m_activeToolBar == toolBar)
|
||||
return;
|
||||
toolBar->setVisible(true);
|
||||
m_activeToolBar->setVisible(false);
|
||||
m_activeToolBar = toolBar;
|
||||
}
|
||||
|
||||
int EditorView::editorCount() const
|
||||
{
|
||||
return m_container->count();
|
||||
}
|
||||
|
||||
QList<IEditor *> EditorView::editors() const
|
||||
{
|
||||
return m_widgetEditorMap.values();
|
||||
}
|
||||
|
||||
|
||||
void EditorView::makeEditorWritable()
|
||||
{
|
||||
CoreImpl::instance()->editorManager()->makeEditorWritable(currentEditor());
|
||||
}
|
||||
|
||||
void EditorView::listSelectionActivated(int index)
|
||||
{
|
||||
EditorManager *em = CoreImpl::instance()->editorManager();
|
||||
QAbstractItemModel *model = m_editorList->model();
|
||||
if (IEditor *editor = model->data(model->index(index, 0), Qt::UserRole).value<IEditor*>()) {
|
||||
em->activateEditor(this, editor);
|
||||
} else {
|
||||
em->activateEditor(model->index(index, 0), this);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorView::listContextMenu(QPoint pos)
|
||||
{
|
||||
QModelIndex index = m_model->index(m_editorList->currentIndex(), 0);
|
||||
QString fileName = m_model->data(index, Qt::UserRole + 1).toString();
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
QMenu menu;
|
||||
menu.addAction(tr("Copy full path to clipboard"));
|
||||
if (menu.exec(m_editorList->mapToGlobal(pos))) {
|
||||
QApplication::clipboard()->setText(QDir::toNativeSeparators(fileName));
|
||||
}
|
||||
}
|
||||
|
||||
void EditorView::updateEditorHistory(IEditor *editor)
|
||||
{
|
||||
if (!editor)
|
||||
return;
|
||||
IFile *file = editor->file();
|
||||
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
QString fileName = file->fileName();
|
||||
QByteArray state = editor->saveState();
|
||||
|
||||
EditLocation location;
|
||||
location.file = file;
|
||||
location.fileName = file->fileName();
|
||||
location.kind = editor->kind();
|
||||
location.state = QVariant(state);
|
||||
|
||||
for(int i = 0; i < m_editorHistory.size(); ++i) {
|
||||
if (m_editorHistory.at(i).file == 0
|
||||
|| m_editorHistory.at(i).file == file
|
||||
){
|
||||
m_editorHistory.removeAt(i--);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
m_editorHistory.prepend(location);
|
||||
}
|
||||
|
||||
void EditorView::addCurrentPositionToNavigationHistory(IEditor *editor, const QByteArray &saveState)
|
||||
{
|
||||
if (editor && editor != currentEditor()) {
|
||||
return; // we only save editor sate for the current editor, when the user interacts
|
||||
}
|
||||
|
||||
if (!editor)
|
||||
editor = currentEditor();
|
||||
if (!editor)
|
||||
return;
|
||||
IFile *file = editor->file();
|
||||
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
QString fileName = file->fileName();
|
||||
QByteArray state;
|
||||
if (saveState.isNull()) {
|
||||
state = editor->saveState();
|
||||
} else {
|
||||
state = saveState;
|
||||
}
|
||||
|
||||
EditLocation location;
|
||||
location.file = file;
|
||||
location.fileName = file->fileName();
|
||||
location.kind = editor->kind();
|
||||
location.state = QVariant(state);
|
||||
m_currentNavigationHistoryPosition = qMin(m_currentNavigationHistoryPosition, m_navigationHistory.size()); // paranoia
|
||||
m_navigationHistory.insert(m_currentNavigationHistoryPosition, location);
|
||||
++m_currentNavigationHistoryPosition;
|
||||
|
||||
while (m_navigationHistory.size() >= 30) {
|
||||
if (m_currentNavigationHistoryPosition > 15) {
|
||||
m_navigationHistory.takeFirst();
|
||||
--m_currentNavigationHistoryPosition;
|
||||
} else {
|
||||
m_navigationHistory.takeLast();
|
||||
}
|
||||
}
|
||||
updateActions();
|
||||
}
|
||||
|
||||
void EditorView::updateActions()
|
||||
{
|
||||
m_goBackAction->setEnabled(canGoBack());
|
||||
m_goForwardAction->setEnabled(canGoForward());
|
||||
}
|
||||
|
||||
void EditorView::updateActionShortcuts()
|
||||
{
|
||||
ActionManager *am = ICore::instance()->actionManager();
|
||||
m_closeButton->setToolTip(am->command(Constants::CLOSE)->stringWithAppendedShortcut(EditorManager::tr("Close")));
|
||||
m_goBackAction->setToolTip(am->command(Constants::GO_BACK)->action()->toolTip());
|
||||
m_goForwardAction->setToolTip(am->command(Constants::GO_FORWARD)->action()->toolTip());
|
||||
}
|
||||
|
||||
void EditorView::copyNavigationHistoryFrom(EditorView* other)
|
||||
{
|
||||
if (!other)
|
||||
return;
|
||||
m_currentNavigationHistoryPosition = other->m_currentNavigationHistoryPosition;
|
||||
m_navigationHistory = other->m_navigationHistory;
|
||||
m_editorHistory = other->m_editorHistory;
|
||||
updateActions();
|
||||
}
|
||||
|
||||
void EditorView::updateCurrentPositionInNavigationHistory()
|
||||
{
|
||||
IEditor *editor = currentEditor();
|
||||
if (!editor || !editor->file())
|
||||
return;
|
||||
|
||||
IFile *file = editor->file();
|
||||
EditLocation *location;
|
||||
if (m_currentNavigationHistoryPosition < m_navigationHistory.size()) {
|
||||
location = &m_navigationHistory[m_currentNavigationHistoryPosition];
|
||||
} else {
|
||||
m_navigationHistory.append(EditLocation());
|
||||
location = &m_navigationHistory[m_navigationHistory.size()-1];
|
||||
}
|
||||
location->file = file;
|
||||
location->fileName = file->fileName();
|
||||
location->kind = editor->kind();
|
||||
location->state = QVariant(editor->saveState());
|
||||
}
|
||||
|
||||
void EditorView::goBackInNavigationHistory()
|
||||
{
|
||||
EditorManager *em = CoreImpl::instance()->editorManager();
|
||||
updateCurrentPositionInNavigationHistory();
|
||||
while (m_currentNavigationHistoryPosition > 0) {
|
||||
--m_currentNavigationHistoryPosition;
|
||||
EditLocation location = m_navigationHistory.at(m_currentNavigationHistoryPosition);
|
||||
IEditor *editor;
|
||||
if (location.file) {
|
||||
editor = em->activateEditor(this, location.file, EditorManager::IgnoreNavigationHistory);
|
||||
} else {
|
||||
editor = em->openEditor(this, location.fileName, location.kind, EditorManager::IgnoreNavigationHistory);
|
||||
if (!editor) {
|
||||
m_navigationHistory.removeAt(m_currentNavigationHistoryPosition);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
editor->restoreState(location.state.toByteArray());
|
||||
break;
|
||||
}
|
||||
updateActions();
|
||||
}
|
||||
|
||||
void EditorView::goForwardInNavigationHistory()
|
||||
{
|
||||
EditorManager *em = CoreImpl::instance()->editorManager();
|
||||
updateCurrentPositionInNavigationHistory();
|
||||
if (m_currentNavigationHistoryPosition >= m_navigationHistory.size()-1)
|
||||
return;
|
||||
++m_currentNavigationHistoryPosition;
|
||||
EditLocation location = m_navigationHistory.at(m_currentNavigationHistoryPosition);
|
||||
IEditor *editor;
|
||||
if (location.file) {
|
||||
editor = em->activateEditor(this, location.file, EditorManager::IgnoreNavigationHistory);
|
||||
} else {
|
||||
editor = em->openEditor(this, location.fileName, location.kind, EditorManager::IgnoreNavigationHistory);
|
||||
if (!editor) {
|
||||
//TODO
|
||||
qDebug() << Q_FUNC_INFO << "can't open file" << location.fileName;
|
||||
return;
|
||||
}
|
||||
}
|
||||
editor->restoreState(location.state.toByteArray());
|
||||
updateActions();
|
||||
}
|
||||
|
||||
|
||||
SplitterOrView::SplitterOrView(OpenEditorsModel *model)
|
||||
{
|
||||
Q_ASSERT(model);
|
||||
m_isRoot = true;
|
||||
m_layout = new QStackedLayout(this);
|
||||
m_view = new EditorView(model);
|
||||
m_splitter = 0;
|
||||
m_layout->addWidget(m_view);
|
||||
}
|
||||
|
||||
SplitterOrView::SplitterOrView(Core::IEditor *editor)
|
||||
{
|
||||
m_isRoot = false;
|
||||
m_layout = new QStackedLayout(this);
|
||||
m_view = new EditorView();
|
||||
if (editor)
|
||||
m_view->addEditor(editor);
|
||||
m_splitter = 0;
|
||||
m_layout->addWidget(m_view);
|
||||
}
|
||||
|
||||
SplitterOrView::~SplitterOrView()
|
||||
{
|
||||
delete m_layout;
|
||||
m_layout = 0;
|
||||
delete m_view;
|
||||
m_view = 0;
|
||||
delete m_splitter;
|
||||
m_splitter = 0;
|
||||
}
|
||||
|
||||
void SplitterOrView::mousePressEvent(QMouseEvent *e)
|
||||
{
|
||||
if (e->button() != Qt::LeftButton)
|
||||
return;
|
||||
setFocus(Qt::MouseFocusReason);
|
||||
CoreImpl::instance()->editorManager()->setCurrentView(this);
|
||||
}
|
||||
|
||||
void SplitterOrView::paintEvent(QPaintEvent *)
|
||||
{
|
||||
if (CoreImpl::instance()->editorManager()->currentSplitterOrView() != this)
|
||||
return;
|
||||
|
||||
if (!m_view || hasEditors())
|
||||
return;
|
||||
|
||||
// Discreet indication where an editor would be if there is none
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
painter.setPen(Qt::NoPen);
|
||||
QColor shadeBrush(Qt::black);
|
||||
shadeBrush.setAlpha(10);
|
||||
painter.setBrush(shadeBrush);
|
||||
const int r = 3;
|
||||
painter.drawRoundedRect(rect().adjusted(r, r, -r, -r), r * 2, r * 2);
|
||||
|
||||
#if 0
|
||||
if (hasFocus()) {
|
||||
#ifdef Q_WS_MAC
|
||||
// With QMacStyle, we have to draw our own focus rect, since I didn't find
|
||||
// a way to draw the nice mac focus rect _inside_ this widget
|
||||
if (qobject_cast<QMacStyle *>(style())) {
|
||||
painter.setPen(Qt::DotLine);
|
||||
painter.setBrush(Qt::NoBrush);
|
||||
painter.setOpacity(0.75);
|
||||
painter.drawRect(rect());
|
||||
} else {
|
||||
#endif
|
||||
QStyleOptionFocusRect option;
|
||||
option.initFrom(this);
|
||||
option.backgroundColor = palette().color(QPalette::Background);
|
||||
|
||||
// Some styles require a certain state flag in order to draw the focus rect
|
||||
option.state |= QStyle::State_KeyboardFocusChange;
|
||||
|
||||
style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, &painter);
|
||||
#ifdef Q_WS_MAC
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SplitterOrView *SplitterOrView::findFirstView()
|
||||
{
|
||||
if (m_splitter) {
|
||||
for (int i = 0; i < m_splitter->count(); ++i) {
|
||||
if (SplitterOrView *splitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(i)))
|
||||
if (SplitterOrView *result = splitterOrView->findFirstView())
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
SplitterOrView *SplitterOrView::findEmptyView()
|
||||
{
|
||||
if (m_splitter) {
|
||||
for (int i = 0; i < m_splitter->count(); ++i) {
|
||||
if (SplitterOrView *splitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(i)))
|
||||
if (SplitterOrView *result = splitterOrView->findEmptyView())
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (!hasEditors())
|
||||
return this;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SplitterOrView *SplitterOrView::findView(Core::IEditor *editor)
|
||||
{
|
||||
if (!editor || hasEditor(editor))
|
||||
return this;
|
||||
if (m_splitter) {
|
||||
for (int i = 0; i < m_splitter->count(); ++i) {
|
||||
if (SplitterOrView *splitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(i)))
|
||||
if (SplitterOrView *result = splitterOrView->findView(editor))
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
SplitterOrView *SplitterOrView::findView(EditorView *view)
|
||||
{
|
||||
if (view == m_view)
|
||||
return this;
|
||||
if (m_splitter) {
|
||||
for (int i = 0; i < m_splitter->count(); ++i) {
|
||||
if (SplitterOrView *splitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(i)))
|
||||
if (SplitterOrView *result = splitterOrView->findView(view))
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
SplitterOrView *SplitterOrView::findSplitter(Core::IEditor *editor)
|
||||
{
|
||||
if (m_splitter) {
|
||||
for (int i = 0; i < m_splitter->count(); ++i) {
|
||||
if (SplitterOrView *splitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(i))) {
|
||||
if (splitterOrView->hasEditor(editor))
|
||||
return this;
|
||||
if (SplitterOrView *result = splitterOrView->findSplitter(editor))
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
SplitterOrView *SplitterOrView::findSplitter(SplitterOrView *child)
|
||||
{
|
||||
if (m_splitter) {
|
||||
for (int i = 0; i < m_splitter->count(); ++i) {
|
||||
if (SplitterOrView *splitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(i))) {
|
||||
if (splitterOrView == child)
|
||||
return this;
|
||||
if (SplitterOrView *result = splitterOrView->findSplitter(child))
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
SplitterOrView *SplitterOrView::findNextView(SplitterOrView *view)
|
||||
{
|
||||
bool found = false;
|
||||
return findNextView_helper(view, &found);
|
||||
}
|
||||
|
||||
SplitterOrView *SplitterOrView::findNextView_helper(SplitterOrView *view, bool *found)
|
||||
{
|
||||
if (*found && m_view) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (this == view) {
|
||||
*found = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (m_splitter) {
|
||||
for (int i = 0; i < m_splitter->count(); ++i) {
|
||||
if (SplitterOrView *splitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(i))) {
|
||||
if (SplitterOrView *result = splitterOrView->findNextView_helper(view, found))
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QSize SplitterOrView::minimumSizeHint() const
|
||||
{
|
||||
if (m_splitter)
|
||||
return m_splitter->minimumSizeHint();
|
||||
return QSize(64, 64);
|
||||
}
|
||||
|
||||
QSplitter *SplitterOrView::takeSplitter()
|
||||
{
|
||||
QSplitter *oldSplitter = m_splitter;
|
||||
if (m_splitter)
|
||||
m_layout->removeWidget(m_splitter);
|
||||
m_splitter = 0;
|
||||
return oldSplitter;
|
||||
}
|
||||
|
||||
EditorView *SplitterOrView::takeView()
|
||||
{
|
||||
EditorView *oldView = m_view;
|
||||
if (m_view)
|
||||
m_layout->removeWidget(m_view);
|
||||
m_view = 0;
|
||||
return oldView;
|
||||
}
|
||||
|
||||
void SplitterOrView::split(Qt::Orientation orientation)
|
||||
{
|
||||
Q_ASSERT(m_view && m_splitter == 0);
|
||||
m_splitter = new MiniSplitter(this);
|
||||
m_splitter->setOrientation(orientation);
|
||||
m_layout->addWidget(m_splitter);
|
||||
EditorManager *em = CoreImpl::instance()->editorManager();
|
||||
Core::IEditor *e = m_view->currentEditor();
|
||||
|
||||
SplitterOrView *view = 0;
|
||||
SplitterOrView *otherView = 0;
|
||||
if (e) {
|
||||
|
||||
m_view->removeEditor(e);
|
||||
m_splitter->addWidget((view = new SplitterOrView(e)));
|
||||
if (e->duplicateSupported()) {
|
||||
Core::IEditor *duplicate = em->duplicateEditor(e);
|
||||
m_splitter->addWidget((otherView = new SplitterOrView(duplicate)));
|
||||
} else {
|
||||
m_splitter->addWidget((otherView = new SplitterOrView()));
|
||||
}
|
||||
} else {
|
||||
m_splitter->addWidget((otherView = new SplitterOrView()));
|
||||
m_splitter->addWidget((view = new SplitterOrView()));
|
||||
}
|
||||
|
||||
m_layout->setCurrentWidget(m_splitter);
|
||||
|
||||
view->view()->copyNavigationHistoryFrom(m_view);
|
||||
view->view()->setCurrentEditor(view->view()->currentEditor());
|
||||
otherView->view()->copyNavigationHistoryFrom(m_view);
|
||||
otherView->view()->setCurrentEditor(otherView->view()->currentEditor());
|
||||
|
||||
if (m_view && !m_isRoot) {
|
||||
em->emptyView(m_view);
|
||||
delete m_view;
|
||||
m_view = 0;
|
||||
}
|
||||
|
||||
if (e)
|
||||
em->activateEditor(view->view(), e);
|
||||
else
|
||||
em->setCurrentView(view);
|
||||
}
|
||||
|
||||
void SplitterOrView::unsplitAll()
|
||||
{
|
||||
m_splitter->hide();
|
||||
m_layout->removeWidget(m_splitter); // workaround Qt bug
|
||||
unsplitAll_helper();
|
||||
delete m_splitter;
|
||||
m_splitter = 0;
|
||||
}
|
||||
|
||||
void SplitterOrView::unsplitAll_helper()
|
||||
{
|
||||
if (!m_isRoot && m_view)
|
||||
CoreImpl::instance()->editorManager()->emptyView(m_view);
|
||||
if (m_splitter) {
|
||||
for (int i = 0; i < m_splitter->count(); ++i) {
|
||||
if (SplitterOrView *splitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(i))) {
|
||||
splitterOrView->unsplitAll_helper();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SplitterOrView::unsplit()
|
||||
{
|
||||
if (!m_splitter)
|
||||
return;
|
||||
|
||||
Q_ASSERT(m_splitter->count() == 1);
|
||||
EditorManager *em = CoreImpl::instance()->editorManager();
|
||||
SplitterOrView *childSplitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(0));
|
||||
QSplitter *oldSplitter = m_splitter;
|
||||
m_splitter = 0;
|
||||
|
||||
if (childSplitterOrView->isSplitter()) {
|
||||
Q_ASSERT(childSplitterOrView->view() == 0);
|
||||
m_splitter = childSplitterOrView->takeSplitter();
|
||||
m_layout->addWidget(m_splitter);
|
||||
m_layout->setCurrentWidget(m_splitter);
|
||||
} else {
|
||||
EditorView *childView = childSplitterOrView->view();
|
||||
Q_ASSERT(childView);
|
||||
if (m_view) {
|
||||
m_view->copyNavigationHistoryFrom(childView);
|
||||
if (IEditor *e = childView->currentEditor()) {
|
||||
childView->removeEditor(e);
|
||||
m_view->addEditor(e);
|
||||
m_view->setCurrentEditor(e);
|
||||
}
|
||||
em->emptyView(childView);
|
||||
} else {
|
||||
m_view = childSplitterOrView->takeView();
|
||||
m_layout->addWidget(m_view);
|
||||
}
|
||||
m_layout->setCurrentWidget(m_view);
|
||||
}
|
||||
delete oldSplitter;
|
||||
em->setCurrentView(findFirstView());
|
||||
}
|
||||
|
||||
|
||||
QByteArray SplitterOrView::saveState() const
|
||||
{
|
||||
QByteArray bytes;
|
||||
QDataStream stream(&bytes, QIODevice::WriteOnly);
|
||||
|
||||
if (m_splitter) {
|
||||
stream << QByteArray("splitter")
|
||||
<< (qint32)m_splitter->orientation()
|
||||
<< m_splitter->saveState()
|
||||
<< static_cast<SplitterOrView*>(m_splitter->widget(0))->saveState()
|
||||
<< static_cast<SplitterOrView*>(m_splitter->widget(1))->saveState();
|
||||
} else {
|
||||
IEditor* e = editor();
|
||||
EditorManager *em = CoreImpl::instance()->editorManager();
|
||||
|
||||
if (e && e == em->currentEditor()) {
|
||||
stream << QByteArray("currenteditor")
|
||||
<< e->file()->fileName() << e->kind() << e->saveState();
|
||||
} else if (e) {
|
||||
stream << QByteArray("editor")
|
||||
<< e->file()->fileName() << e->kind() << e->saveState();
|
||||
} else {
|
||||
stream << QByteArray("empty");
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void SplitterOrView::restoreState(const QByteArray &state)
|
||||
{
|
||||
QDataStream stream(state);
|
||||
QByteArray mode;
|
||||
stream >> mode;
|
||||
if (mode == "splitter") {
|
||||
qint32 orientation;
|
||||
QByteArray splitter, first, second;
|
||||
stream >> orientation >> splitter >> first >> second;
|
||||
split((Qt::Orientation)orientation);
|
||||
m_splitter->restoreState(splitter);
|
||||
static_cast<SplitterOrView*>(m_splitter->widget(0))->restoreState(first);
|
||||
static_cast<SplitterOrView*>(m_splitter->widget(1))->restoreState(second);
|
||||
} else if (mode == "editor" || mode == "currenteditor") {
|
||||
EditorManager *em = CoreImpl::instance()->editorManager();
|
||||
QString fileName;
|
||||
QByteArray kind;
|
||||
QByteArray editorState;
|
||||
stream >> fileName >> kind >> editorState;
|
||||
IEditor *e = em->openEditor(view(), fileName, kind, Core::EditorManager::IgnoreNavigationHistory
|
||||
| Core::EditorManager::NoActivate);
|
||||
|
||||
if (!e) {
|
||||
QModelIndex idx = em->openedEditorsModel()->firstRestoredEditor();
|
||||
if (idx.isValid())
|
||||
em->activateEditor(idx, view(), Core::EditorManager::IgnoreNavigationHistory
|
||||
| Core::EditorManager::NoActivate);
|
||||
}
|
||||
|
||||
if (e) {
|
||||
e->restoreState(editorState);
|
||||
if (mode == "currenteditor")
|
||||
em->setCurrentEditor(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,217 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef EDITORVIEW_H
|
||||
#define EDITORVIEW_H
|
||||
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QSplitter>
|
||||
#include <QtGui/QStackedLayout>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <coreplugin/ifile.h>
|
||||
|
||||
#include <QtCore/QMap>
|
||||
#include <QtGui/QSortFilterProxyModel>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QComboBox;
|
||||
class QToolButton;
|
||||
class QLabel;
|
||||
class QStackedWidget;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
|
||||
class IEditor;
|
||||
class OpenEditorsModel;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
struct EditLocation {
|
||||
QPointer<IFile> file;
|
||||
QString fileName;
|
||||
QString kind;
|
||||
QVariant state;
|
||||
};
|
||||
|
||||
class EditorView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EditorView(OpenEditorsModel *model = 0, QWidget *parent = 0);
|
||||
virtual ~EditorView();
|
||||
|
||||
int editorCount() const;
|
||||
void addEditor(IEditor *editor);
|
||||
void removeEditor(IEditor *editor);
|
||||
IEditor *currentEditor() const;
|
||||
void setCurrentEditor(IEditor *editor);
|
||||
|
||||
bool hasEditor(IEditor *editor) const;
|
||||
|
||||
QList<IEditor *> editors() const;
|
||||
void showEditorInfoBar(const QString &kind,
|
||||
const QString &infoText,
|
||||
const QString &buttonText,
|
||||
QObject *object, const char *member);
|
||||
void hideEditorInfoBar(const QString &kind);
|
||||
|
||||
void showEditorStatusBar(const QString &kind,
|
||||
const QString &infoText,
|
||||
const QString &buttonText,
|
||||
QObject *object, const char *member);
|
||||
void hideEditorStatusBar(const QString &kind);
|
||||
|
||||
public slots:
|
||||
void closeView();
|
||||
|
||||
private slots:
|
||||
void updateEditorStatus(Core::IEditor *editor = 0);
|
||||
void checkEditorStatus();
|
||||
void makeEditorWritable();
|
||||
void listSelectionActivated(int index);
|
||||
void listContextMenu(QPoint);
|
||||
|
||||
private:
|
||||
void updateToolBar(IEditor *editor);
|
||||
void checkProjectLoaded(IEditor *editor);
|
||||
|
||||
OpenEditorsModel *m_model;
|
||||
QWidget *m_toolBar;
|
||||
QWidget *m_activeToolBar;
|
||||
QStackedWidget *m_container;
|
||||
QComboBox *m_editorList;
|
||||
QToolButton *m_closeButton;
|
||||
QToolButton *m_lockButton;
|
||||
QWidget *m_defaultToolBar;
|
||||
QString m_infoWidgetKind;
|
||||
QFrame *m_infoWidget;
|
||||
QLabel *m_infoWidgetLabel;
|
||||
QToolButton *m_infoWidgetButton;
|
||||
IEditor *m_editorForInfoWidget;
|
||||
QString m_statusWidgetKind;
|
||||
QFrame *m_statusHLine;
|
||||
QFrame *m_statusWidget;
|
||||
QLabel *m_statusWidgetLabel;
|
||||
QToolButton *m_statusWidgetButton;
|
||||
QList<IEditor *> m_editors;
|
||||
QMap<QWidget *, IEditor *> m_widgetEditorMap;
|
||||
|
||||
QList<EditLocation> m_navigationHistory;
|
||||
QList<EditLocation> m_editorHistory;
|
||||
int m_currentNavigationHistoryPosition;
|
||||
void updateCurrentPositionInNavigationHistory();
|
||||
QAction *m_goBackAction;
|
||||
QAction *m_goForwardAction;
|
||||
void updateActions();
|
||||
|
||||
|
||||
public:
|
||||
inline bool canGoForward() const { return m_currentNavigationHistoryPosition < m_navigationHistory.size()-1; }
|
||||
inline bool canGoBack() const { return m_currentNavigationHistoryPosition > 0; }
|
||||
|
||||
public slots:
|
||||
void goBackInNavigationHistory();
|
||||
void goForwardInNavigationHistory();
|
||||
void updateActionShortcuts();
|
||||
|
||||
public:
|
||||
void addCurrentPositionToNavigationHistory(IEditor *editor = 0, const QByteArray &saveState = QByteArray());
|
||||
inline QList<EditLocation> editorHistory() const { return m_editorHistory; }
|
||||
|
||||
void copyNavigationHistoryFrom(EditorView* other);
|
||||
void updateEditorHistory(IEditor *editor);
|
||||
};
|
||||
|
||||
class SplitterOrView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SplitterOrView(OpenEditorsModel *model); // creates a root splitter
|
||||
SplitterOrView(Core::IEditor *editor = 0);
|
||||
~SplitterOrView();
|
||||
|
||||
void split(Qt::Orientation orientation);
|
||||
void unsplit();
|
||||
|
||||
inline bool isView() const { return m_view != 0; }
|
||||
inline bool isRoot() const { return m_isRoot; }
|
||||
|
||||
inline bool isSplitter() const { return m_splitter != 0; }
|
||||
inline Core::IEditor *editor() const { return m_view ? m_view->currentEditor() : 0; }
|
||||
inline QList<Core::IEditor *> editors() const { return m_view ? m_view->editors() : QList<Core::IEditor*>(); }
|
||||
inline bool hasEditor(Core::IEditor *editor) const { return m_view && m_view->hasEditor(editor); }
|
||||
inline bool hasEditors() const { return m_view && m_view->editorCount() != 0; }
|
||||
inline EditorView *view() const { return m_view; }
|
||||
inline QSplitter *splitter() const { return m_splitter; }
|
||||
QSplitter *takeSplitter();
|
||||
EditorView *takeView();
|
||||
|
||||
QByteArray saveState() const;
|
||||
void restoreState(const QByteArray &);
|
||||
|
||||
SplitterOrView *findView(Core::IEditor *editor);
|
||||
SplitterOrView *findView(EditorView *view);
|
||||
SplitterOrView *findFirstView();
|
||||
SplitterOrView *findEmptyView();
|
||||
SplitterOrView *findSplitter(Core::IEditor *editor);
|
||||
SplitterOrView *findSplitter(SplitterOrView *child);
|
||||
|
||||
SplitterOrView *findNextView(SplitterOrView *view);
|
||||
|
||||
QSize sizeHint() const { return minimumSizeHint(); }
|
||||
QSize minimumSizeHint() const;
|
||||
|
||||
void unsplitAll();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
|
||||
|
||||
private:
|
||||
void unsplitAll_helper();
|
||||
SplitterOrView *findNextView_helper(SplitterOrView *view, bool *found);
|
||||
bool m_isRoot;
|
||||
QStackedLayout *m_layout;
|
||||
EditorView *m_view;
|
||||
QSplitter *m_splitter;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif // EDITORVIEW_H
|
@ -1,55 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "ieditor.h"
|
||||
|
||||
/*!
|
||||
\class Core::IEditor
|
||||
\brief The IEditor is an interface for providing different editors for different file types.
|
||||
|
||||
Classes that implement this interface are for example the editors for
|
||||
C++ files, ui-files and resource files.
|
||||
|
||||
Whenever a user wants to edit or create a file, the EditorManager scans all
|
||||
EditorFactoryInterfaces for suitable editors. The selected EditorFactory
|
||||
is then asked to create an editor, which must implement this interface.
|
||||
|
||||
Guidelines for implementing:
|
||||
\list
|
||||
\o displayName() is used as a user visible description of the document (usually filename w/o path).
|
||||
\o kind() must be the same value as the kind() of the corresponding EditorFactory.
|
||||
\o The changed() signal should be emitted when the modified state of the document changes
|
||||
(so /bold{not} every time the document changes, but /bold{only once}).
|
||||
\o If duplication is supported, you need to ensure that all duplicates
|
||||
return the same file().
|
||||
\endlist
|
||||
|
||||
\sa Core::EditorFactoryInterface Core::IContext
|
||||
|
||||
*/
|
@ -1,74 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef IEDITOR_H
|
||||
#define IEDITOR_H
|
||||
|
||||
#include <coreplugin/core_global.h>
|
||||
#include <coreplugin/icontext.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class IFile;
|
||||
|
||||
class CORE_EXPORT IEditor : public IContext
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
IEditor(QObject *parent = 0) : IContext(parent) {}
|
||||
virtual ~IEditor() {}
|
||||
|
||||
virtual bool createNew(const QString &contents = QString()) = 0;
|
||||
virtual bool open(const QString &fileName = QString()) = 0;
|
||||
virtual IFile *file() = 0;
|
||||
virtual const char *kind() const = 0;
|
||||
virtual QString displayName() const = 0;
|
||||
virtual void setDisplayName(const QString &title) = 0;
|
||||
|
||||
virtual bool duplicateSupported() const = 0;
|
||||
virtual IEditor *duplicate(QWidget *parent) = 0;
|
||||
|
||||
virtual QByteArray saveState() const = 0;
|
||||
virtual bool restoreState(const QByteArray &state) = 0;
|
||||
|
||||
virtual int currentLine() const { return 0; }
|
||||
virtual int currentColumn() const { return 0; }
|
||||
|
||||
virtual bool isTemporary() const = 0;
|
||||
|
||||
virtual QWidget *toolBar() = 0;
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif // IEDITOR_H
|
@ -1,51 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef IEDITORFACTORY_H
|
||||
#define IEDITORFACTORY_H
|
||||
|
||||
#include <coreplugin/ifilefactory.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class IEditor;
|
||||
|
||||
class CORE_EXPORT IEditorFactory : public Core::IFileFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
IEditorFactory(QObject *parent = 0) : IFileFactory(parent) {}
|
||||
virtual ~IEditorFactory() {}
|
||||
|
||||
virtual IEditor *createEditor(QWidget *parent) = 0;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif // IEDITORFACTORY_H
|
@ -1,66 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "iexternaleditor.h"
|
||||
|
||||
/*!
|
||||
\class Core::IExternalEditor
|
||||
\mainclass
|
||||
|
||||
\brief Core::IExternalEditor allows for registering an external
|
||||
Editor in the \gui{Open With...} dialogs .
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn IExternalEditor::IExternalEditor(QObject *parent)
|
||||
\internal
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn IExternalEditor::~IExternalEditor()
|
||||
\internal
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QStringList IExternalEditor::mimeTypes() const
|
||||
Returns the mime type the editor supports
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QString IExternalEditor::kind() const
|
||||
Returns the editor kind (identifying string).
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
||||
\fn bool IExternalEditor::startEditor(const QString &fileName, QString *errorMessage) = 0;
|
||||
|
||||
Opens the editor with \param fileName. Returns true on success or false
|
||||
on failure along with the error in \param errorMessage.
|
||||
*/
|
@ -1,54 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef IEXTERNALEDITOR_H
|
||||
#define IEXTERNALEDITOR_H
|
||||
|
||||
#include <coreplugin/core_global.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class CORE_EXPORT IExternalEditor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit IExternalEditor(QObject *parent = 0) : QObject(parent) {}
|
||||
virtual ~IExternalEditor() {}
|
||||
|
||||
virtual QStringList mimeTypes() const = 0;
|
||||
virtual QString kind() const = 0;
|
||||
|
||||
virtual bool startEditor(const QString &fileName, QString *errorMessage) = 0;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif // IEXTERNALEDITOR_H
|
@ -1,303 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "openeditorsmodel.h"
|
||||
#include "ieditor.h"
|
||||
#include "ifile.h"
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtGui/QIcon>
|
||||
|
||||
Q_DECLARE_METATYPE(Core::IEditor*)
|
||||
|
||||
namespace Core {
|
||||
|
||||
QString OpenEditorsModel::Entry::fileName() const {
|
||||
return editor ? editor->file()->fileName() : m_fileName;
|
||||
}
|
||||
QString OpenEditorsModel::Entry::displayName() const {
|
||||
return editor ? editor->displayName() : m_displayName;
|
||||
}
|
||||
QByteArray OpenEditorsModel::Entry::kind() const
|
||||
{
|
||||
return editor ? QByteArray(editor->kind()) : m_kind;
|
||||
}
|
||||
|
||||
int OpenEditorsModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return 2;
|
||||
}
|
||||
|
||||
int OpenEditorsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
return m_editors.count();
|
||||
return 0;
|
||||
}
|
||||
|
||||
QList<IEditor *> OpenEditorsModel::editors() const
|
||||
{
|
||||
QList<IEditor *> result;
|
||||
foreach (Entry entry, m_editors)
|
||||
if (entry.editor)
|
||||
result += entry.editor;
|
||||
return result;
|
||||
}
|
||||
|
||||
void OpenEditorsModel::addEditor(IEditor *editor, bool isDuplicate)
|
||||
{
|
||||
if (!editor)
|
||||
return;
|
||||
|
||||
if (isDuplicate) {
|
||||
m_duplicateEditors.append(editor);
|
||||
return;
|
||||
}
|
||||
|
||||
Entry entry;
|
||||
entry.editor = editor;
|
||||
addEntry(entry);
|
||||
}
|
||||
|
||||
void OpenEditorsModel::addRestoredEditor(const QString &fileName, const QString &displayName, const QByteArray &kind)
|
||||
{
|
||||
Entry entry;
|
||||
entry.m_fileName = fileName;
|
||||
entry.m_displayName = displayName;
|
||||
entry.m_kind = kind;
|
||||
addEntry(entry);
|
||||
}
|
||||
|
||||
QModelIndex OpenEditorsModel::firstRestoredEditor() const
|
||||
{
|
||||
for (int i = 0; i < m_editors.count(); ++i)
|
||||
if (!m_editors.at(i).editor)
|
||||
return createIndex(i, 0);
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
void OpenEditorsModel::addEntry(const Entry &entry)
|
||||
{
|
||||
QString fileName = entry.fileName();
|
||||
|
||||
int previousIndex = findFileName(fileName);
|
||||
if (previousIndex >= 0) {
|
||||
if (entry.editor && m_editors.at(previousIndex).editor == 0) {
|
||||
m_editors[previousIndex] = entry;
|
||||
connect(entry.editor, SIGNAL(changed()), this, SLOT(itemChanged()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int index;
|
||||
QString displayName = entry.displayName();
|
||||
for (index = 0; index < m_editors.count(); ++index) {
|
||||
if (displayName < m_editors.at(index).displayName())
|
||||
break;
|
||||
}
|
||||
|
||||
beginInsertRows(QModelIndex(), index, index);
|
||||
m_editors.insert(index, entry);
|
||||
if (entry.editor)
|
||||
connect(entry.editor, SIGNAL(changed()), this, SLOT(itemChanged()));
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
|
||||
int OpenEditorsModel::findEditor(IEditor *editor) const
|
||||
{
|
||||
for (int i = 0; i < m_editors.count(); ++i)
|
||||
if (m_editors.at(i).editor == editor)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int OpenEditorsModel::findFileName(const QString &filename) const
|
||||
{
|
||||
if (filename.isEmpty())
|
||||
return -1;
|
||||
for (int i = 0; i < m_editors.count(); ++i) {
|
||||
if (m_editors.at(i).fileName() == filename)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void OpenEditorsModel::removeEditor(IEditor *editor)
|
||||
{
|
||||
m_duplicateEditors.removeAll(editor);
|
||||
int idx = findEditor(editor);
|
||||
if (idx < 0)
|
||||
return;
|
||||
beginRemoveRows(QModelIndex(), idx, idx);
|
||||
m_editors.removeAt(idx);
|
||||
endRemoveRows();
|
||||
disconnect(editor, SIGNAL(changed()), this, SLOT(itemChanged()));
|
||||
}
|
||||
|
||||
void OpenEditorsModel::removeEditor(const QModelIndex &index)
|
||||
{
|
||||
int idx = index.row();
|
||||
if (idx < 0)
|
||||
return;
|
||||
IEditor *editor= m_editors.at(idx).editor;
|
||||
beginRemoveRows(QModelIndex(), idx, idx);
|
||||
m_editors.removeAt(idx);
|
||||
endRemoveRows();
|
||||
if (editor)
|
||||
disconnect(editor, SIGNAL(changed()), this, SLOT(itemChanged()));
|
||||
}
|
||||
|
||||
void OpenEditorsModel::removeAllRestoredEditors()
|
||||
{
|
||||
for (int i = m_editors.count()-1; i >= 0; --i) {
|
||||
if (!m_editors.at(i).editor) {
|
||||
beginRemoveRows(QModelIndex(), i, i);
|
||||
m_editors.removeAt(i);
|
||||
endRemoveRows();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int OpenEditorsModel::restoredEditorCount() const
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = m_editors.count()-1; i >= 0; --i) {
|
||||
if (!m_editors.at(i).editor) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool OpenEditorsModel::isDuplicate(IEditor *editor) const
|
||||
{
|
||||
return editor && m_duplicateEditors.contains(editor);
|
||||
}
|
||||
|
||||
IEditor *OpenEditorsModel::originalForDuplicate(IEditor *duplicate) const
|
||||
{
|
||||
IFile *file = duplicate->file();
|
||||
foreach(Entry e, m_editors)
|
||||
if (e.editor && e.editor->file() == file)
|
||||
return e.editor;
|
||||
return 0;
|
||||
}
|
||||
|
||||
QList<IEditor *> OpenEditorsModel::duplicatesFor(IEditor *editor) const
|
||||
{
|
||||
QList<IEditor *> result;
|
||||
IFile *file = editor->file();
|
||||
foreach(IEditor *e, m_duplicateEditors)
|
||||
if (e->file() == file)
|
||||
result += e;
|
||||
return result;
|
||||
}
|
||||
|
||||
void OpenEditorsModel::makeOriginal(IEditor *duplicate)
|
||||
{
|
||||
Q_ASSERT(duplicate && isDuplicate(duplicate));
|
||||
IEditor *original = originalForDuplicate(duplicate);
|
||||
Q_ASSERT(original);
|
||||
int i = findEditor(original);
|
||||
m_editors[i].editor = duplicate;
|
||||
m_duplicateEditors.removeOne(duplicate);
|
||||
m_duplicateEditors.append(original);
|
||||
disconnect(original, SIGNAL(changed()), this, SLOT(itemChanged()));
|
||||
connect(duplicate, SIGNAL(changed()), this, SLOT(itemChanged()));
|
||||
}
|
||||
|
||||
void OpenEditorsModel::emitDataChanged(IEditor *editor)
|
||||
{
|
||||
int idx = findEditor(editor);
|
||||
if (idx < 0)
|
||||
return;
|
||||
QModelIndex mindex = index(idx, 0);
|
||||
emit dataChanged(mindex, mindex);
|
||||
}
|
||||
|
||||
QModelIndex OpenEditorsModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
if (column < 0 || column > 1 || row < 0 || row >= m_editors.count())
|
||||
return QModelIndex();
|
||||
return createIndex(row, column);
|
||||
}
|
||||
|
||||
QVariant OpenEditorsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || (index.column() != 0 && role < Qt::UserRole))
|
||||
return QVariant();
|
||||
Entry e = m_editors.at(index.row());
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
return (e.editor && e.editor->file()->isModified())
|
||||
? e.displayName() + QLatin1String("*")
|
||||
: e.displayName();
|
||||
case Qt::DecorationRole:
|
||||
return (e.editor && e.editor->file()->isReadOnly())
|
||||
? QIcon(QLatin1String(":/core/images/locked.png"))
|
||||
: QIcon();
|
||||
case Qt::ToolTipRole:
|
||||
return e.fileName().isEmpty()
|
||||
? e.displayName()
|
||||
: QDir::toNativeSeparators(e.fileName());
|
||||
case Qt::UserRole:
|
||||
return qVariantFromValue(e.editor);
|
||||
case Qt::UserRole + 1:
|
||||
return e.fileName();
|
||||
case Qt::UserRole + 2:
|
||||
return e.editor ? QByteArray(e.editor->kind()) : e.kind();
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex OpenEditorsModel::indexOf(IEditor *editor) const
|
||||
{
|
||||
int idx = findEditor(originalForDuplicate(editor));
|
||||
return createIndex(idx, 0);
|
||||
}
|
||||
|
||||
QString OpenEditorsModel::displayNameForFile(IFile *file) const
|
||||
{
|
||||
for (int i = 0; i < m_editors.count(); ++i)
|
||||
if (m_editors.at(i).editor && m_editors.at(i).editor->file() == file)
|
||||
return m_editors.at(i).editor->displayName();
|
||||
return QString();
|
||||
}
|
||||
|
||||
void OpenEditorsModel::itemChanged()
|
||||
{
|
||||
emitDataChanged(qobject_cast<IEditor*>(sender()));
|
||||
}
|
||||
|
||||
} // namespace Core
|
@ -1,100 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef OPENEDITORSMODEL_H
|
||||
#define OPENEDITORSMODEL_H
|
||||
|
||||
#include "../core_global.h"
|
||||
|
||||
#include <QtCore/QAbstractItemModel>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class IEditor;
|
||||
class IFile;
|
||||
|
||||
class CORE_EXPORT OpenEditorsModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
OpenEditorsModel(QObject *parent) : QAbstractItemModel(parent) {}
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
QModelIndex parent(const QModelIndex &/*index*/) const { return QModelIndex(); }
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
|
||||
|
||||
void addEditor(IEditor *editor, bool isDuplicate = false);
|
||||
void addRestoredEditor(const QString &fileName, const QString &displayName, const QByteArray &kind);
|
||||
QModelIndex firstRestoredEditor() const;
|
||||
|
||||
struct Entry {
|
||||
Entry():editor(0){}
|
||||
IEditor *editor;
|
||||
QString fileName() const;
|
||||
QString displayName() const;
|
||||
QByteArray kind() const;
|
||||
QString m_fileName;
|
||||
QString m_displayName;
|
||||
QByteArray m_kind;
|
||||
};
|
||||
QList<Entry> entries() const { return m_editors; }
|
||||
|
||||
inline IEditor *editorAt(int row) const { return m_editors.at(row).editor; }
|
||||
|
||||
void removeEditor(IEditor *editor);
|
||||
void removeEditor(const QModelIndex &index);
|
||||
|
||||
void removeAllRestoredEditors();
|
||||
int restoredEditorCount() const;
|
||||
void emitDataChanged(IEditor *editor);
|
||||
|
||||
QList<IEditor *> editors() const;
|
||||
bool isDuplicate(IEditor *editor) const;
|
||||
QList<IEditor *> duplicatesFor(IEditor *editor) const;
|
||||
IEditor *originalForDuplicate(IEditor *duplicate) const;
|
||||
void makeOriginal(IEditor *duplicate);
|
||||
QModelIndex indexOf(IEditor *editor) const;
|
||||
|
||||
QString displayNameForFile(IFile *file) const;
|
||||
|
||||
private slots:
|
||||
void itemChanged();
|
||||
|
||||
private:
|
||||
void addEntry(const Entry &entry);
|
||||
int findEditor(IEditor *editor) const;
|
||||
int findFileName(const QString &filename) const;
|
||||
QList<Entry> m_editors;
|
||||
QList<IEditor *>m_duplicateEditors;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif // OPENEDITORSMODEL_H
|
@ -1,261 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "openeditorsview.h"
|
||||
#include "editormanager.h"
|
||||
#include "editorview.h"
|
||||
#include "openeditorsmodel.h"
|
||||
#include "icore.h"
|
||||
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/filemanager.h>
|
||||
#include <coreplugin/uniqueidmanager.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QStyle>
|
||||
#include <QtGui/QStyleOption>
|
||||
#include <QtGui/QHeaderView>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#ifdef Q_WS_MAC
|
||||
#include <qmacstyle_mac.h>
|
||||
#endif
|
||||
|
||||
Q_DECLARE_METATYPE(Core::IEditor*)
|
||||
|
||||
using namespace Core;
|
||||
using namespace Core::Internal;
|
||||
|
||||
|
||||
OpenEditorsDelegate::OpenEditorsDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void OpenEditorsDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
if (option.state & QStyle::State_MouseOver) {
|
||||
if ((QApplication::mouseButtons() & Qt::LeftButton) == 0)
|
||||
pressedIndex = QModelIndex();
|
||||
QBrush brush = option.palette.alternateBase();
|
||||
if (index == pressedIndex)
|
||||
brush = option.palette.dark();
|
||||
painter->fillRect(option.rect, brush);
|
||||
}
|
||||
|
||||
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
|
||||
if (index.column() == 1 && option.state & QStyle::State_MouseOver) {
|
||||
QIcon icon((option.state & QStyle::State_Selected) ? ":/core/images/closebutton.png"
|
||||
: ":/core/images/darkclosebutton.png");
|
||||
|
||||
QRect iconRect(option.rect.right() - option.rect.height(),
|
||||
option.rect.top(),
|
||||
option.rect.height(),
|
||||
option.rect.height());
|
||||
|
||||
icon.paint(painter, iconRect, Qt::AlignRight | Qt::AlignVCenter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////
|
||||
// OpenEditorsWidget
|
||||
////
|
||||
|
||||
OpenEditorsWidget::OpenEditorsWidget()
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
setWindowTitle(tr("Open Documents"));
|
||||
setWindowIcon(QIcon(Constants::ICON_DIR));
|
||||
setFocusProxy(m_ui.editorList);
|
||||
m_ui.editorList->viewport()->setAttribute(Qt::WA_Hover);
|
||||
m_ui.editorList->setItemDelegate((m_delegate = new OpenEditorsDelegate(this)));
|
||||
m_ui.editorList->header()->hide();
|
||||
m_ui.editorList->setIndentation(0);
|
||||
m_ui.editorList->setTextElideMode(Qt::ElideMiddle);
|
||||
m_ui.editorList->setFrameStyle(QFrame::NoFrame);
|
||||
m_ui.editorList->setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
EditorManager *em = EditorManager::instance();
|
||||
m_ui.editorList->setModel(em->openedEditorsModel());
|
||||
m_ui.editorList->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_ui.editorList->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
m_ui.editorList->header()->setStretchLastSection(false);
|
||||
m_ui.editorList->header()->setResizeMode(0, QHeaderView::Stretch);
|
||||
m_ui.editorList->header()->setResizeMode(1, QHeaderView::Fixed);
|
||||
m_ui.editorList->header()->resizeSection(1, 16);
|
||||
m_ui.editorList->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_ui.editorList->installEventFilter(this);
|
||||
|
||||
connect(em, SIGNAL(currentEditorChanged(Core::IEditor*)),
|
||||
this, SLOT(updateCurrentItem(Core::IEditor*)));
|
||||
connect(m_ui.editorList, SIGNAL(clicked(QModelIndex)),
|
||||
this, SLOT(handleClicked(QModelIndex)));
|
||||
connect(m_ui.editorList, SIGNAL(pressed(QModelIndex)),
|
||||
this, SLOT(handlePressed(QModelIndex)));
|
||||
|
||||
connect(m_ui.editorList, SIGNAL(customContextMenuRequested(QPoint)),
|
||||
this, SLOT(contextMenuRequested(QPoint)));
|
||||
}
|
||||
|
||||
OpenEditorsWidget::~OpenEditorsWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void OpenEditorsWidget::updateCurrentItem(Core::IEditor *editor)
|
||||
{
|
||||
if (!editor) {
|
||||
m_ui.editorList->clearSelection();
|
||||
return;
|
||||
}
|
||||
EditorManager *em = EditorManager::instance();
|
||||
m_ui.editorList->setCurrentIndex(em->openedEditorsModel()->indexOf(editor));
|
||||
m_ui.editorList->selectionModel()->select(m_ui.editorList->currentIndex(),
|
||||
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||
m_ui.editorList->scrollTo(m_ui.editorList->currentIndex());
|
||||
}
|
||||
|
||||
bool OpenEditorsWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (obj == m_ui.editorList && event->type() == QEvent::KeyPress
|
||||
&& m_ui.editorList->currentIndex().isValid()) {
|
||||
QKeyEvent *ke = static_cast<QKeyEvent*>(event);
|
||||
if ((ke->key() == Qt::Key_Return
|
||||
|| ke->key() == Qt::Key_Enter)
|
||||
&& ke->modifiers() == 0) {
|
||||
activateEditor(m_ui.editorList->currentIndex());
|
||||
return true;
|
||||
} else if ((ke->key() == Qt::Key_Delete
|
||||
|| ke->key() == Qt::Key_Backspace)
|
||||
&& ke->modifiers() == 0) {
|
||||
closeEditor(m_ui.editorList->currentIndex());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void OpenEditorsWidget::handlePressed(const QModelIndex &index)
|
||||
{
|
||||
if (index.column() == 0) {
|
||||
activateEditor(index);
|
||||
} else if (index.column() == 1) {
|
||||
m_delegate->pressedIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenEditorsWidget::handleClicked(const QModelIndex &index)
|
||||
{
|
||||
if (index.column() == 1) { // the funky close button
|
||||
closeEditor(index);
|
||||
|
||||
// work around a bug in itemviews where the delegate wouldn't get the QStyle::State_MouseOver
|
||||
QPoint cursorPos = QCursor::pos();
|
||||
QWidget *vp = m_ui.editorList->viewport();
|
||||
QMouseEvent e(QEvent::MouseMove, vp->mapFromGlobal(cursorPos), cursorPos, Qt::NoButton, 0, 0);
|
||||
QCoreApplication::sendEvent(vp, &e);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenEditorsWidget::activateEditor(const QModelIndex &index)
|
||||
{
|
||||
m_ui.editorList->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||
EditorManager::instance()->activateEditor(index);
|
||||
}
|
||||
|
||||
void OpenEditorsWidget::closeEditor(const QModelIndex &index)
|
||||
{
|
||||
EditorManager::instance()->closeEditor(index);
|
||||
// work around selection changes
|
||||
updateCurrentItem(EditorManager::instance()->currentEditor());
|
||||
}
|
||||
|
||||
void OpenEditorsWidget::contextMenuRequested(QPoint pos)
|
||||
{
|
||||
const QModelIndex index = m_ui.editorList->indexAt(pos);
|
||||
QMenu contextMenu;
|
||||
QAction *closeEditor = contextMenu.addAction(
|
||||
index.isValid() ? tr("Close %1").arg(index.data().toString())
|
||||
: tr("Close Editor"));
|
||||
QAction *closeOtherEditors = contextMenu.addAction(
|
||||
index.isValid() ? tr("Close All Except %1").arg(index.data().toString())
|
||||
: tr("Close Other Editors"));
|
||||
QAction *closeAllEditors = contextMenu.addAction(tr("Close All Editors"));
|
||||
|
||||
if (!index.isValid()) {
|
||||
closeEditor->setEnabled(false);
|
||||
closeOtherEditors->setEnabled(false);
|
||||
}
|
||||
|
||||
if (EditorManager::instance()->openedEditors().isEmpty())
|
||||
closeAllEditors->setEnabled(false);
|
||||
|
||||
QAction *action = contextMenu.exec(m_ui.editorList->mapToGlobal(pos));
|
||||
if (action == 0)
|
||||
return;
|
||||
if (action == closeEditor)
|
||||
EditorManager::instance()->closeEditor(index);
|
||||
else if (action == closeAllEditors)
|
||||
EditorManager::instance()->closeAllEditors();
|
||||
else if (action == closeOtherEditors)
|
||||
EditorManager::instance()->closeOtherEditors(index.data(Qt::UserRole).value<Core::IEditor*>());
|
||||
}
|
||||
|
||||
///
|
||||
// OpenEditorsViewFactory
|
||||
///
|
||||
|
||||
NavigationView OpenEditorsViewFactory::createWidget()
|
||||
{
|
||||
NavigationView n;
|
||||
n.widget = new OpenEditorsWidget();
|
||||
return n;
|
||||
}
|
||||
|
||||
QString OpenEditorsViewFactory::displayName()
|
||||
{
|
||||
return OpenEditorsWidget::tr("Open Documents");
|
||||
}
|
||||
|
||||
QKeySequence OpenEditorsViewFactory::activationSequence()
|
||||
{
|
||||
return QKeySequence(Qt::ALT + Qt::Key_O);
|
||||
}
|
||||
|
||||
OpenEditorsViewFactory::OpenEditorsViewFactory()
|
||||
{
|
||||
}
|
||||
|
||||
OpenEditorsViewFactory::~OpenEditorsViewFactory()
|
||||
{
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef OPENEDITORSVIEW_H
|
||||
#define OPENEDITORSVIEW_H
|
||||
|
||||
#include "ui_openeditorsview.h"
|
||||
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
#include <coreplugin/inavigationwidgetfactory.h>
|
||||
|
||||
#include <QtCore/QList>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QKeySequence>
|
||||
#include <QtGui/QAbstractButton>
|
||||
#include <QtGui/QTreeWidgetItem>
|
||||
#include <QtGui/QStyledItemDelegate>
|
||||
|
||||
namespace Core {
|
||||
namespace Internal {
|
||||
|
||||
class OpenEditorsDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
OpenEditorsDelegate(QObject *parent = 0);
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const;
|
||||
|
||||
mutable QModelIndex pressedIndex;
|
||||
};
|
||||
|
||||
|
||||
class OpenEditorsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
OpenEditorsWidget();
|
||||
~OpenEditorsWidget();
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
private slots:
|
||||
void handleClicked(const QModelIndex &);
|
||||
void handlePressed(const QModelIndex &);
|
||||
void updateCurrentItem(Core::IEditor*);
|
||||
void contextMenuRequested(QPoint pos);
|
||||
|
||||
private:
|
||||
void activateEditor(const QModelIndex &index);
|
||||
void closeEditor(const QModelIndex &index);
|
||||
|
||||
Ui::OpenEditorsView m_ui;
|
||||
QWidget *m_widget;
|
||||
OpenEditorsDelegate *m_delegate;
|
||||
};
|
||||
|
||||
class OpenEditorsViewFactory : public Core::INavigationWidgetFactory
|
||||
{
|
||||
public:
|
||||
OpenEditorsViewFactory();
|
||||
virtual ~OpenEditorsViewFactory();
|
||||
QString displayName();
|
||||
virtual QKeySequence activationSequence();
|
||||
Core::NavigationView createWidget();
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
|
||||
#endif // OPENEDITORSVIEW_H
|
@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OpenEditorsView</class>
|
||||
<widget class="QWidget" name="OpenEditorsView">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>263</width>
|
||||
<height>217</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QTreeView" name="editorList">
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -1,296 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "openeditorswindow.h"
|
||||
#include "openeditorsmodel.h"
|
||||
#include "editormanager.h"
|
||||
#include "editorview.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QtGui/QHeaderView>
|
||||
|
||||
Q_DECLARE_METATYPE(Core::Internal::EditorView*)
|
||||
Q_DECLARE_METATYPE(Core::IFile *)
|
||||
|
||||
using namespace Core;
|
||||
using namespace Core::Internal;
|
||||
|
||||
const int OpenEditorsWindow::WIDTH = 300;
|
||||
const int OpenEditorsWindow::HEIGHT = 200;
|
||||
const int OpenEditorsWindow::MARGIN = 4;
|
||||
|
||||
OpenEditorsWindow::OpenEditorsWindow(QWidget *parent) :
|
||||
QWidget(parent, Qt::Popup),
|
||||
m_editorList(new QTreeWidget(this))
|
||||
{
|
||||
resize(QSize(WIDTH, HEIGHT));
|
||||
m_editorList->setColumnCount(1);
|
||||
m_editorList->header()->hide();
|
||||
m_editorList->setIndentation(0);
|
||||
m_editorList->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_editorList->setSelectionBehavior(QAbstractItemView::SelectItems);
|
||||
m_editorList->setTextElideMode(Qt::ElideMiddle);
|
||||
#ifdef Q_WS_MAC
|
||||
m_editorList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
#endif
|
||||
m_editorList->installEventFilter(this);
|
||||
m_editorList->setGeometry(MARGIN, MARGIN, WIDTH-2*MARGIN, HEIGHT-2*MARGIN);
|
||||
|
||||
connect(m_editorList, SIGNAL(itemClicked(QTreeWidgetItem*, int)),
|
||||
this, SLOT(editorClicked(QTreeWidgetItem*)));
|
||||
|
||||
m_autoHide.setSingleShot(true);
|
||||
connect(&m_autoHide, SIGNAL(timeout()), this, SLOT(selectAndHide()));
|
||||
}
|
||||
|
||||
void OpenEditorsWindow::selectAndHide()
|
||||
{
|
||||
selectEditor(m_editorList->currentItem());
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
void OpenEditorsWindow::setVisible(bool visible)
|
||||
{
|
||||
QWidget::setVisible(visible);
|
||||
if (visible) {
|
||||
m_autoHide.start(600);
|
||||
setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenEditorsWindow::isCentering()
|
||||
{
|
||||
int internalMargin = m_editorList->viewport()->mapTo(m_editorList, QPoint(0,0)).y();
|
||||
QRect rect0 = m_editorList->visualItemRect(m_editorList->topLevelItem(0));
|
||||
QRect rect1 = m_editorList->visualItemRect(m_editorList->topLevelItem(m_editorList->topLevelItemCount()-1));
|
||||
int height = rect1.y() + rect1.height() - rect0.y();
|
||||
height += 2*internalMargin + 2*MARGIN;
|
||||
if (height > HEIGHT)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool OpenEditorsWindow::event(QEvent *e) {
|
||||
if (e->type() == QEvent::KeyRelease) {
|
||||
QKeyEvent *ke = static_cast<QKeyEvent*>(e);
|
||||
m_autoHide.stop();
|
||||
if (ke->modifiers() == 0
|
||||
/*HACK this is to overcome some event inconsistencies between platforms*/
|
||||
|| (ke->modifiers() == Qt::AltModifier && (ke->key() == Qt::Key_Alt || ke->key() == -1))) {
|
||||
selectAndHide();
|
||||
}
|
||||
}
|
||||
return QWidget::event(e);
|
||||
}
|
||||
|
||||
bool OpenEditorsWindow::eventFilter(QObject *obj, QEvent *e)
|
||||
{
|
||||
if (obj == m_editorList) {
|
||||
if (e->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *ke = static_cast<QKeyEvent*>(e);
|
||||
if (ke->key() == Qt::Key_Escape) {
|
||||
setVisible(false);
|
||||
return true;
|
||||
}
|
||||
if (ke->key() == Qt::Key_Return) {
|
||||
selectEditor(m_editorList->currentItem());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return QWidget::eventFilter(obj, e);
|
||||
}
|
||||
|
||||
void OpenEditorsWindow::focusInEvent(QFocusEvent *)
|
||||
{
|
||||
m_editorList->setFocus();
|
||||
}
|
||||
|
||||
void OpenEditorsWindow::selectUpDown(bool up)
|
||||
{
|
||||
int itemCount = m_editorList->topLevelItemCount();
|
||||
if (itemCount < 2)
|
||||
return;
|
||||
int index = m_editorList->indexOfTopLevelItem(m_editorList->currentItem());
|
||||
if (index < 0)
|
||||
return;
|
||||
QTreeWidgetItem *editor = 0;
|
||||
int count = 0;
|
||||
while (!editor && count < itemCount) {
|
||||
if (up) {
|
||||
index--;
|
||||
if (index < 0)
|
||||
index = itemCount-1;
|
||||
} else {
|
||||
index++;
|
||||
if (index >= itemCount)
|
||||
index = 0;
|
||||
}
|
||||
editor = m_editorList->topLevelItem(index);
|
||||
count++;
|
||||
}
|
||||
if (editor) {
|
||||
m_editorList->setCurrentItem(editor);
|
||||
ensureCurrentVisible();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenEditorsWindow::selectPreviousEditor()
|
||||
{
|
||||
selectUpDown(false);
|
||||
}
|
||||
|
||||
void OpenEditorsWindow::selectNextEditor()
|
||||
{
|
||||
selectUpDown(true);
|
||||
}
|
||||
|
||||
void OpenEditorsWindow::centerOnItem(int selectedIndex)
|
||||
{
|
||||
if (selectedIndex >= 0) {
|
||||
QTreeWidgetItem *item;
|
||||
int num = m_editorList->topLevelItemCount();
|
||||
int rotate = selectedIndex-(num-1)/2;
|
||||
for (int i = 0; i < rotate; ++i) {
|
||||
item = m_editorList->takeTopLevelItem(0);
|
||||
m_editorList->addTopLevelItem(item);
|
||||
}
|
||||
rotate = -rotate;
|
||||
for (int i = 0; i < rotate; ++i) {
|
||||
item = m_editorList->takeTopLevelItem(num-1);
|
||||
m_editorList->insertTopLevelItem(0, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpenEditorsWindow::setEditors(EditorView *mainView, EditorView *view, OpenEditorsModel *model)
|
||||
{
|
||||
static const QIcon lockedIcon(QLatin1String(":/core/images/locked.png"));
|
||||
static const QIcon emptyIcon(QLatin1String(":/core/images/empty14.png"));
|
||||
|
||||
m_editorList->clear();
|
||||
bool first = true;
|
||||
|
||||
QSet<IFile*> filesDone;
|
||||
foreach (const EditLocation &hi, view->editorHistory()) {
|
||||
if (hi.file.isNull() || filesDone.contains(hi.file))
|
||||
continue;
|
||||
QString title = model->displayNameForFile(hi.file);
|
||||
QTC_ASSERT(!title.isEmpty(), continue;)
|
||||
filesDone.insert(hi.file.data());
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
if (hi.file->isModified())
|
||||
title += tr("*");
|
||||
item->setIcon(0, hi.file->isReadOnly() ? lockedIcon : emptyIcon);
|
||||
item->setText(0, title);
|
||||
item->setToolTip(0, hi.file->fileName());
|
||||
item->setData(0, Qt::UserRole, QVariant::fromValue(hi.file.data()));
|
||||
item->setData(0, Qt::UserRole+1, QVariant::fromValue(view));
|
||||
item->setTextAlignment(0, Qt::AlignLeft);
|
||||
|
||||
m_editorList->addTopLevelItem(item);
|
||||
|
||||
if (first){
|
||||
m_editorList->setCurrentItem(item);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
// add missing editors from the main view
|
||||
if (mainView != view) {
|
||||
foreach (const EditLocation &hi, mainView->editorHistory()) {
|
||||
if (hi.file.isNull() || filesDone.contains(hi.file))
|
||||
continue;
|
||||
filesDone.insert(hi.file.data());
|
||||
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
|
||||
QString title = model->displayNameForFile(hi.file);
|
||||
if (hi.file->isModified())
|
||||
title += tr("*");
|
||||
item->setIcon(0, hi.file->isReadOnly() ? lockedIcon : emptyIcon);
|
||||
item->setText(0, title);
|
||||
item->setToolTip(0, hi.file->fileName());
|
||||
item->setData(0, Qt::UserRole, QVariant::fromValue(hi.file.data()));
|
||||
item->setData(0, Qt::UserRole+1, QVariant::fromValue(view));
|
||||
item->setData(0, Qt::UserRole+2, QVariant::fromValue(hi.kind));
|
||||
item->setTextAlignment(0, Qt::AlignLeft);
|
||||
|
||||
m_editorList->addTopLevelItem(item);
|
||||
|
||||
if (first){
|
||||
m_editorList->setCurrentItem(item);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add purely restored editors which are not initialised yet
|
||||
foreach (OpenEditorsModel::Entry entry, model->entries()) {
|
||||
if (entry.editor)
|
||||
continue;
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
QString title = entry.displayName();
|
||||
item->setIcon(0, emptyIcon);
|
||||
item->setText(0, title);
|
||||
item->setToolTip(0, entry.fileName());
|
||||
item->setData(0, Qt::UserRole+2, QVariant::fromValue(entry.kind()));
|
||||
item->setTextAlignment(0, Qt::AlignLeft);
|
||||
|
||||
m_editorList->addTopLevelItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OpenEditorsWindow::selectEditor(QTreeWidgetItem *item)
|
||||
{
|
||||
if (!item)
|
||||
return;
|
||||
if (IFile *file = item->data(0, Qt::UserRole).value<IFile*>()) {
|
||||
EditorView *view = item->data(0, Qt::UserRole+1).value<EditorView*>();
|
||||
EditorManager::instance()->activateEditor(view, file);
|
||||
} else {
|
||||
EditorManager::instance()->openEditor(item->toolTip(0), item->data(0, Qt::UserRole+2).toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
void OpenEditorsWindow::editorClicked(QTreeWidgetItem *item)
|
||||
{
|
||||
selectEditor(item);
|
||||
setFocus();
|
||||
}
|
||||
|
||||
|
||||
void OpenEditorsWindow::ensureCurrentVisible()
|
||||
{
|
||||
m_editorList->scrollTo(m_editorList->currentIndex(), QAbstractItemView::PositionAtCenter);
|
||||
}
|
||||
|
@ -1,94 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef OPENEDITORSWINDOW_H
|
||||
#define OPENEDITORSWINDOW_H
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <QtGui/QFocusEvent>
|
||||
#include <QtGui/QTreeWidget>
|
||||
#include <QtDebug>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class IEditor;
|
||||
class OpenEditorsModel;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class EditorHistoryItem;
|
||||
class EditorView;
|
||||
|
||||
class OpenEditorsWindow : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Mode {ListMode, HistoryMode };
|
||||
|
||||
OpenEditorsWindow(QWidget *parent = 0);
|
||||
~OpenEditorsWindow() {}
|
||||
|
||||
void setEditors(EditorView *mainView, EditorView *view, OpenEditorsModel *model);
|
||||
|
||||
bool event(QEvent *e);
|
||||
bool eventFilter(QObject *src, QEvent *e);
|
||||
void focusInEvent(QFocusEvent *);
|
||||
void setVisible(bool visible);
|
||||
void selectNextEditor();
|
||||
void selectPreviousEditor();
|
||||
|
||||
private slots:
|
||||
void editorClicked(QTreeWidgetItem *item);
|
||||
void selectEditor(QTreeWidgetItem *item);
|
||||
void selectAndHide();
|
||||
|
||||
private:
|
||||
static const int WIDTH;
|
||||
static const int HEIGHT;
|
||||
static const int MARGIN;
|
||||
|
||||
static void updateItem(QTreeWidgetItem *item, IEditor *editor);
|
||||
void ensureCurrentVisible();
|
||||
bool isCentering();
|
||||
void centerOnItem(int selectedIndex);
|
||||
void selectUpDown(bool up);
|
||||
|
||||
bool isSameFile(IEditor *editorA, IEditor *editorB) const;
|
||||
|
||||
QTreeWidget *m_editorList;
|
||||
QTimer m_autoHide;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
#endif // OPENEDITORSWINDOW_H
|
@ -1,634 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "filemanager.h"
|
||||
|
||||
#include "editormanager.h"
|
||||
#include "ieditor.h"
|
||||
#include "icore.h"
|
||||
#include "ifile.h"
|
||||
#include "iversioncontrol.h"
|
||||
#include "mainwindow.h"
|
||||
#include "mimedatabase.h"
|
||||
#include "saveitemsdialog.h"
|
||||
#include "vcsmanager.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QFileSystemWatcher>
|
||||
#include <QtGui/QFileDialog>
|
||||
#include <QtGui/QMessageBox>
|
||||
|
||||
using namespace Core;
|
||||
using namespace Core::Internal;
|
||||
|
||||
/*!
|
||||
\class FileManager
|
||||
\mainclass
|
||||
\inheaderfile filemanager.h
|
||||
\brief Manages a set of IFile objects.
|
||||
|
||||
The FileManager service monitors a set of IFile's. Plugins should register
|
||||
files they work with at the service. The files the IFile's point to will be
|
||||
monitored at filesystem level. If a file changes, the status of the IFile's
|
||||
will be adjusted accordingly. Furthermore, on application exit the user will
|
||||
be asked to save all modified files.
|
||||
|
||||
Different IFile objects in the set can point to the same file in the
|
||||
filesystem. The monitoring of a file can be blocked by blockFileChange(), and
|
||||
enabled again by unblockFileChange().
|
||||
|
||||
The FileManager service also provides two convenience methods for saving
|
||||
files: saveModifiedFiles() and saveModifiedFilesSilently(). Both take a list
|
||||
of FileInterfaces as an argument, and return the list of files which were
|
||||
_not_ saved.
|
||||
|
||||
The service also manages the list of recent files to be shown to the user
|
||||
(see addToRecentFiles() and recentFiles()).
|
||||
*/
|
||||
|
||||
static const char *settingsGroup = "RecentFiles";
|
||||
static const char *filesKey = "Files";
|
||||
|
||||
FileManager::FileManager(MainWindow *mw)
|
||||
: QObject(mw),
|
||||
m_mainWindow(mw),
|
||||
m_fileWatcher(new QFileSystemWatcher(this)),
|
||||
m_blockActivated(false)
|
||||
{
|
||||
connect(m_fileWatcher, SIGNAL(fileChanged(QString)),
|
||||
this, SLOT(changedFile(QString)));
|
||||
connect(m_mainWindow, SIGNAL(windowActivated()),
|
||||
this, SLOT(mainWindowActivated()));
|
||||
connect(Core::ICore::instance(), SIGNAL(contextChanged(Core::IContext*)),
|
||||
this, SLOT(syncWithEditor(Core::IContext*)));
|
||||
|
||||
QSettings *s = m_mainWindow->settings();
|
||||
s->beginGroup(QLatin1String(settingsGroup));
|
||||
m_recentFiles = s->value(QLatin1String(filesKey), QStringList()).toStringList();
|
||||
s->endGroup();
|
||||
for (QStringList::iterator it = m_recentFiles.begin(); it != m_recentFiles.end(); ) {
|
||||
if (QFileInfo(*it).isFile()) {
|
||||
++it;
|
||||
} else {
|
||||
it = m_recentFiles.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool FileManager::addFiles(const QList<IFile *> &files)
|
||||
|
||||
Adds a list of IFile's to the collection.
|
||||
|
||||
Returns true if the file specified by \a files have not been yet part of the file list.
|
||||
*/
|
||||
bool FileManager::addFiles(const QList<IFile *> &files)
|
||||
{
|
||||
bool filesAdded = false;
|
||||
foreach (IFile *file, files) {
|
||||
if (!file || m_managedFiles.contains(file))
|
||||
continue;
|
||||
connect(file, SIGNAL(changed()), this, SLOT(checkForNewFileName()));
|
||||
connect(file, SIGNAL(destroyed(QObject *)), this, SLOT(fileDestroyed(QObject *)));
|
||||
filesAdded = true;
|
||||
addWatch(fixFileName(file->fileName()));
|
||||
updateFileInfo(file);
|
||||
}
|
||||
return filesAdded;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool FileManager::addFile(IFile *files)
|
||||
|
||||
Adds a IFile object to the collection.
|
||||
|
||||
Returns true if the file specified by \a file has not been yet part of the file list.
|
||||
*/
|
||||
bool FileManager::addFile(IFile *file)
|
||||
{
|
||||
return addFiles(QList<IFile *>() << file);
|
||||
}
|
||||
|
||||
void FileManager::fileDestroyed(QObject *obj)
|
||||
{
|
||||
// we can't use qobject_cast here, because meta data is already destroyed
|
||||
IFile *file = static_cast<IFile*>(obj);
|
||||
const QString filename = m_managedFiles.value(file).fileName;
|
||||
m_managedFiles.remove(file);
|
||||
removeWatch(filename);
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool FileManager::removeFile(IFile *file)
|
||||
|
||||
Removes a IFile object from the collection.
|
||||
|
||||
Returns true if the file specified by \a file has been part of the file list.
|
||||
*/
|
||||
bool FileManager::removeFile(IFile *file)
|
||||
{
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
disconnect(file, SIGNAL(changed()), this, SLOT(checkForNewFileName()));
|
||||
disconnect(file, SIGNAL(destroyed(QObject *)), this, SLOT(fileDestroyed(QObject *)));
|
||||
|
||||
if (!m_managedFiles.contains(file))
|
||||
return false;
|
||||
const FileInfo info = m_managedFiles.take(file);
|
||||
const QString filename = info.fileName;
|
||||
removeWatch(filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileManager::addWatch(const QString &filename)
|
||||
{
|
||||
if (!filename.isEmpty() && managedFiles(filename).isEmpty())
|
||||
m_fileWatcher->addPath(filename);
|
||||
}
|
||||
|
||||
void FileManager::removeWatch(const QString &filename)
|
||||
{
|
||||
if (!filename.isEmpty() && managedFiles(filename).isEmpty())
|
||||
m_fileWatcher->removePath(filename);
|
||||
}
|
||||
|
||||
void FileManager::checkForNewFileName()
|
||||
{
|
||||
IFile *file = qobject_cast<IFile *>(sender());
|
||||
QTC_ASSERT(file, return);
|
||||
const QString newfilename = fixFileName(file->fileName());
|
||||
const QString oldfilename = m_managedFiles.value(file).fileName;
|
||||
if (!newfilename.isEmpty() && newfilename != oldfilename) {
|
||||
m_managedFiles[file].fileName = newfilename;
|
||||
removeWatch(oldfilename);
|
||||
addWatch(newfilename);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Rename to nativeFileName
|
||||
QString FileManager::fixFileName(const QString &fileName)
|
||||
{
|
||||
QString s = fileName;
|
||||
#ifdef Q_OS_WIN
|
||||
s = s.toLower();
|
||||
#endif
|
||||
if (!QFile::exists(s))
|
||||
return QDir::toNativeSeparators(s);
|
||||
return QFileInfo(QDir::toNativeSeparators(s)).canonicalFilePath();
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool FileManager::isFileManaged(const QString &fileName) const
|
||||
|
||||
Returns true if at least one IFile in the set points to \a fileName.
|
||||
*/
|
||||
bool FileManager::isFileManaged(const QString &fileName) const
|
||||
{
|
||||
if (fileName.isEmpty())
|
||||
return false;
|
||||
|
||||
return !managedFiles(fixFileName(fileName)).isEmpty();
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QList<IFile*> FileManager::modifiedFiles() const
|
||||
|
||||
Returns the list of IFile's that have been modified.
|
||||
*/
|
||||
QList<IFile *> FileManager::modifiedFiles() const
|
||||
{
|
||||
QList<IFile *> modifiedFiles;
|
||||
|
||||
const QMap<IFile*, FileInfo>::const_iterator cend = m_managedFiles.constEnd();
|
||||
for (QMap<IFile*, FileInfo>::const_iterator i = m_managedFiles.constBegin(); i != cend; ++i) {
|
||||
IFile *fi = i.key();
|
||||
if (fi->isModified())
|
||||
modifiedFiles << fi;
|
||||
}
|
||||
return modifiedFiles;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void FileManager::blockFileChange(IFile *file)
|
||||
|
||||
Blocks the monitoring of the file the \a file argument points to.
|
||||
*/
|
||||
void FileManager::blockFileChange(IFile *file)
|
||||
{
|
||||
if (!file->fileName().isEmpty())
|
||||
m_fileWatcher->removePath(file->fileName());
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void FileManager::unblockFileChange(IFile *file)
|
||||
|
||||
Enables the monitoring of the file the \a file argument points to, and update the status of the corresponding IFile's.
|
||||
*/
|
||||
void FileManager::unblockFileChange(IFile *file)
|
||||
{
|
||||
foreach (IFile *managedFile, managedFiles(file->fileName()))
|
||||
updateFileInfo(managedFile);
|
||||
if (!file->fileName().isEmpty())
|
||||
m_fileWatcher->addPath(file->fileName());
|
||||
}
|
||||
|
||||
void FileManager::updateFileInfo(IFile *file)
|
||||
{
|
||||
const QString fixedname = fixFileName(file->fileName());
|
||||
const QFileInfo fi(file->fileName());
|
||||
FileInfo info;
|
||||
info.fileName = fixedname;
|
||||
info.modified = fi.lastModified();
|
||||
info.permissions = fi.permissions();
|
||||
m_managedFiles.insert(file, info);
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QList<IFile*> FileManager::saveModifiedFilesSilently(const QList<IFile*> &files)
|
||||
|
||||
Tries to save the files listed in \a files . Returns the files that could not be saved.
|
||||
*/
|
||||
QList<IFile *> FileManager::saveModifiedFilesSilently(const QList<IFile *> &files)
|
||||
{
|
||||
return saveModifiedFiles(files, 0, true, QString());
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QList<IFile*> FileManager::saveModifiedFiles(const QList<IFile*> &files, bool *cancelled, const QString &message)
|
||||
|
||||
Asks the user whether to save the files listed in \a files . Returns the files that have not been saved.
|
||||
*/
|
||||
QList<IFile *> FileManager::saveModifiedFiles(const QList<IFile *> &files,
|
||||
bool *cancelled, const QString &message,
|
||||
const QString &alwaysSaveMessage,
|
||||
bool *alwaysSave)
|
||||
{
|
||||
return saveModifiedFiles(files, cancelled, false, message, alwaysSaveMessage, alwaysSave);
|
||||
}
|
||||
|
||||
static QMessageBox::StandardButton skipFailedPrompt(QWidget *parent, const QString &fileName)
|
||||
{
|
||||
return QMessageBox::question(parent,
|
||||
FileManager::tr("Cannot save file"),
|
||||
FileManager::tr("Cannot save changes to '%1'. Do you want to continue and lose your changes?").arg(fileName),
|
||||
QMessageBox::YesToAll| QMessageBox::Yes|QMessageBox::No,
|
||||
QMessageBox::No);
|
||||
}
|
||||
|
||||
QList<IFile *> FileManager::saveModifiedFiles(const QList<IFile *> &files,
|
||||
bool *cancelled,
|
||||
bool silently,
|
||||
const QString &message,
|
||||
const QString &alwaysSaveMessage,
|
||||
bool *alwaysSave)
|
||||
{
|
||||
if (cancelled)
|
||||
(*cancelled) = false;
|
||||
|
||||
QList<IFile *> notSaved;
|
||||
QMap<IFile *, QString> modifiedFilesMap;
|
||||
QList<IFile *> modifiedFiles;
|
||||
|
||||
foreach (IFile *file, files) {
|
||||
if (file->isModified()) {
|
||||
QString name = file->fileName();
|
||||
if (name.isEmpty())
|
||||
name = file->suggestedFileName();
|
||||
|
||||
// There can be several FileInterfaces pointing to the same file
|
||||
// Select one that is not readonly.
|
||||
if (!(modifiedFilesMap.values().contains(name)
|
||||
&& file->isReadOnly()))
|
||||
modifiedFilesMap.insert(file, name);
|
||||
}
|
||||
}
|
||||
modifiedFiles = modifiedFilesMap.keys();
|
||||
if (!modifiedFiles.isEmpty()) {
|
||||
QList<IFile *> filesToSave;
|
||||
if (silently) {
|
||||
filesToSave = modifiedFiles;
|
||||
} else {
|
||||
SaveItemsDialog dia(m_mainWindow, modifiedFiles);
|
||||
if (!message.isEmpty())
|
||||
dia.setMessage(message);
|
||||
if (!alwaysSaveMessage.isNull())
|
||||
dia.setAlwaysSaveMessage(alwaysSaveMessage);
|
||||
if (dia.exec() != QDialog::Accepted) {
|
||||
if (cancelled)
|
||||
(*cancelled) = true;
|
||||
if (alwaysSave)
|
||||
*alwaysSave = dia.alwaysSaveChecked();
|
||||
notSaved = modifiedFiles;
|
||||
return notSaved;
|
||||
}
|
||||
if (alwaysSave)
|
||||
*alwaysSave = dia.alwaysSaveChecked();
|
||||
filesToSave = dia.itemsToSave();
|
||||
}
|
||||
|
||||
bool yestoall = false;
|
||||
foreach (IFile *file, filesToSave) {
|
||||
if (file->isReadOnly()) {
|
||||
QString directory = QFileInfo(file->fileName()).absolutePath();
|
||||
IVersionControl *versionControl = m_mainWindow->vcsManager()->findVersionControlForDirectory(directory);
|
||||
if (versionControl)
|
||||
versionControl->vcsOpen(file->fileName());
|
||||
}
|
||||
if (!file->isReadOnly() && !file->fileName().isEmpty()) {
|
||||
blockFileChange(file);
|
||||
const bool ok = file->save();
|
||||
unblockFileChange(file);
|
||||
if (!ok)
|
||||
notSaved.append(file);
|
||||
} else if (QFile::exists(file->fileName()) && !file->isSaveAsAllowed()) {
|
||||
if (yestoall)
|
||||
continue;
|
||||
const QFileInfo fi(file->fileName());
|
||||
switch (skipFailedPrompt(m_mainWindow, fi.fileName())) {
|
||||
case QMessageBox::YesToAll:
|
||||
yestoall = true;
|
||||
break;
|
||||
case QMessageBox::No:
|
||||
if (cancelled)
|
||||
*cancelled = true;
|
||||
return filesToSave;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
QString fileName = getSaveAsFileName(file);
|
||||
bool ok = false;
|
||||
if (!fileName.isEmpty()) {
|
||||
blockFileChange(file);
|
||||
ok = file->save(fileName);
|
||||
file->checkPermissions();
|
||||
unblockFileChange(file);
|
||||
}
|
||||
if (!ok)
|
||||
notSaved.append(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return notSaved;
|
||||
}
|
||||
|
||||
QString FileManager::getSaveFileNameWithExtension(const QString &title, const QString &path,
|
||||
const QString &fileFilter, const QString &extension)
|
||||
{
|
||||
QString fileName;
|
||||
bool repeat;
|
||||
do {
|
||||
repeat = false;
|
||||
fileName = QFileDialog::getSaveFileName(m_mainWindow, title, path, fileFilter);
|
||||
if (!fileName.isEmpty() && !extension.isEmpty() && !fileName.endsWith(extension)) {
|
||||
fileName.append(extension);
|
||||
if (QFile::exists(fileName)) {
|
||||
if (QMessageBox::warning(m_mainWindow, tr("Overwrite?"),
|
||||
tr("An item named '%1' already exists at this location. Do you want to overwrite it?").arg(fileName),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
|
||||
repeat = true;
|
||||
}
|
||||
}
|
||||
} while (repeat);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QString FileManager::getSaveAsFileName(IFile *file)
|
||||
|
||||
Asks the user for a new file name (Save File As) for /arg file.
|
||||
*/
|
||||
QString FileManager::getSaveAsFileName(IFile *file)
|
||||
{
|
||||
if (!file)
|
||||
return QLatin1String("");
|
||||
QString absoluteFilePath = file->fileName();
|
||||
const QFileInfo fi(absoluteFilePath);
|
||||
QString fileName = fi.fileName();
|
||||
QString path = fi.absolutePath();
|
||||
if (absoluteFilePath.isEmpty()) {
|
||||
fileName = file->suggestedFileName();
|
||||
const QString defaultPath = file->defaultPath();
|
||||
if (!defaultPath.isEmpty())
|
||||
path = defaultPath;
|
||||
}
|
||||
QString filterString;
|
||||
QString preferredSuffix;
|
||||
if (const MimeType mt = Core::ICore::instance()->mimeDatabase()->findByFile(fi)) {
|
||||
filterString = mt.filterString();
|
||||
preferredSuffix = mt.preferredSuffix();
|
||||
}
|
||||
|
||||
absoluteFilePath = getSaveFileNameWithExtension(tr("Save File As"),
|
||||
path + QDir::separator() + fileName,
|
||||
filterString,
|
||||
preferredSuffix);
|
||||
return absoluteFilePath;
|
||||
}
|
||||
|
||||
void FileManager::changedFile(const QString &file)
|
||||
{
|
||||
const bool wasempty = m_changedFiles.isEmpty();
|
||||
foreach (IFile *fileinterface, managedFiles(file))
|
||||
m_changedFiles << fileinterface;
|
||||
if (wasempty && !m_changedFiles.isEmpty()) {
|
||||
QTimer::singleShot(200, this, SLOT(checkForReload()));
|
||||
}
|
||||
}
|
||||
|
||||
void FileManager::mainWindowActivated()
|
||||
{
|
||||
//we need to do this asynchronously because
|
||||
//opening a dialog ("Reload?") in a windowactivated event
|
||||
//freezes on Mac
|
||||
QTimer::singleShot(0, this, SLOT(checkForReload()));
|
||||
}
|
||||
|
||||
void FileManager::checkForReload()
|
||||
{
|
||||
if (QApplication::activeWindow() == m_mainWindow &&
|
||||
!m_blockActivated && !m_changedFiles.isEmpty()) {
|
||||
m_blockActivated = true;
|
||||
const QList<QPointer<IFile> > changed = m_changedFiles;
|
||||
m_changedFiles.clear();
|
||||
IFile::ReloadBehavior behavior = EditorManager::instance()->reloadBehavior();
|
||||
foreach (IFile *f, changed) {
|
||||
if (!f)
|
||||
continue;
|
||||
QFileInfo fi(f->fileName());
|
||||
FileInfo info = m_managedFiles.value(f);
|
||||
if (info.modified != fi.lastModified()
|
||||
|| info.permissions != fi.permissions()) {
|
||||
if (info.modified != fi.lastModified())
|
||||
f->modified(&behavior);
|
||||
else {
|
||||
IFile::ReloadBehavior tempBeh =
|
||||
IFile::ReloadPermissions;
|
||||
f->modified(&tempBeh);
|
||||
}
|
||||
updateFileInfo(f);
|
||||
|
||||
// the file system watchers loses inodes when a file is removed/renamed. Work around it.
|
||||
m_fileWatcher->removePath(f->fileName());
|
||||
m_fileWatcher->addPath(f->fileName());
|
||||
}
|
||||
}
|
||||
m_blockActivated = false;
|
||||
checkForReload();
|
||||
}
|
||||
}
|
||||
|
||||
void FileManager::syncWithEditor(Core::IContext *context)
|
||||
{
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
Core::IEditor *editor = Core::EditorManager::instance()->currentEditor();
|
||||
if (editor && (editor->widget() == context->widget()))
|
||||
setCurrentFile(editor->file()->fileName());
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void FileManager::addToRecentFiles(const QString &fileName)
|
||||
|
||||
Adds the \a fileName to the list of recent files.
|
||||
*/
|
||||
void FileManager::addToRecentFiles(const QString &fileName)
|
||||
{
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
QString prettyFileName(QDir::toNativeSeparators(fileName));
|
||||
m_recentFiles.removeAll(prettyFileName);
|
||||
if (m_recentFiles.count() > m_maxRecentFiles)
|
||||
m_recentFiles.removeLast();
|
||||
m_recentFiles.prepend(prettyFileName);
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QStringList FileManager::recentFiles() const
|
||||
|
||||
Returns the list of recent files.
|
||||
*/
|
||||
QStringList FileManager::recentFiles() const
|
||||
{
|
||||
return m_recentFiles;
|
||||
}
|
||||
|
||||
void FileManager::saveRecentFiles()
|
||||
{
|
||||
QSettings *s = m_mainWindow->settings();
|
||||
s->beginGroup(QLatin1String(settingsGroup));
|
||||
s->setValue(QLatin1String(filesKey), m_recentFiles);
|
||||
s->endGroup();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
The current file is e.g. the file currently opened when an editor is active,
|
||||
or the selected file in case a Project Explorer is active ...
|
||||
|
||||
\sa currentFile
|
||||
*/
|
||||
void FileManager::setCurrentFile(const QString &filePath)
|
||||
{
|
||||
if (m_currentFile == filePath)
|
||||
return;
|
||||
m_currentFile = filePath;
|
||||
emit currentFileChanged(m_currentFile);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the absolute path of the current file
|
||||
|
||||
The current file is e.g. the file currently opened when an editor is active,
|
||||
or the selected file in case a Project Explorer is active ...
|
||||
|
||||
\sa setCurrentFile
|
||||
*/
|
||||
QString FileManager::currentFile() const
|
||||
{
|
||||
return m_currentFile;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QList<IFile*> FileManager::managedFiles(const QString &fileName) const
|
||||
|
||||
Returns the list one IFile's in the set that point to \a fileName.
|
||||
*/
|
||||
QList<IFile *> FileManager::managedFiles(const QString &fileName) const
|
||||
{
|
||||
const QString fixedName = fixFileName(fileName);
|
||||
QList<IFile *> result;
|
||||
if (!fixedName.isEmpty()) {
|
||||
const QMap<IFile*, FileInfo>::const_iterator cend = m_managedFiles.constEnd();
|
||||
for (QMap<IFile*, FileInfo>::const_iterator i = m_managedFiles.constBegin(); i != cend; ++i) {
|
||||
if (i.value().fileName == fixedName)
|
||||
result << i.key();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
FileChangeBlocker::FileChangeBlocker(const QString &fileName)
|
||||
: m_reload(false)
|
||||
{
|
||||
Core::FileManager *fm = Core::ICore::instance()->fileManager();
|
||||
m_files = fm->managedFiles(fileName);
|
||||
foreach (Core::IFile *file, m_files)
|
||||
fm->blockFileChange(file);
|
||||
}
|
||||
|
||||
FileChangeBlocker::~FileChangeBlocker()
|
||||
{
|
||||
Core::IFile::ReloadBehavior tempBehavior = Core::IFile::ReloadAll;
|
||||
Core::FileManager *fm = Core::ICore::instance()->fileManager();
|
||||
foreach (Core::IFile *file, m_files) {
|
||||
if (m_reload)
|
||||
file->modified(&tempBehavior);
|
||||
fm->unblockFileChange(file);
|
||||
}
|
||||
}
|
||||
|
||||
void FileChangeBlocker::setModifiedReload(bool b)
|
||||
{
|
||||
m_reload = b;
|
||||
}
|
||||
|
||||
bool FileChangeBlocker::modifiedReload() const
|
||||
{
|
||||
return m_reload;
|
||||
}
|
@ -1,160 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef FILEMANAGER_H
|
||||
#define FILEMANAGER_H
|
||||
|
||||
#include <coreplugin/core_global.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QFileSystemWatcher;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
|
||||
class ICore;
|
||||
class IContext;
|
||||
class IFile;
|
||||
|
||||
namespace Internal {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class CORE_EXPORT FileManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
struct FileInfo
|
||||
{
|
||||
QString fileName;
|
||||
QDateTime modified;
|
||||
QFile::Permissions permissions;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit FileManager(Internal::MainWindow *ew);
|
||||
|
||||
// file pool to monitor
|
||||
bool addFiles(const QList<IFile *> &files);
|
||||
bool addFile(IFile *file);
|
||||
bool removeFile(IFile *file);
|
||||
bool isFileManaged(const QString &fileName) const;
|
||||
QList<IFile *> managedFiles(const QString &fileName) const;
|
||||
QList<IFile *> modifiedFiles() const;
|
||||
|
||||
void blockFileChange(IFile *file);
|
||||
void unblockFileChange(IFile *file);
|
||||
|
||||
// recent files
|
||||
void addToRecentFiles(const QString &fileName);
|
||||
QStringList recentFiles() const;
|
||||
void saveRecentFiles();
|
||||
|
||||
// current file
|
||||
void setCurrentFile(const QString &filePath);
|
||||
QString currentFile() const;
|
||||
|
||||
// helper methods
|
||||
static QString fixFileName(const QString &fileName);
|
||||
|
||||
QString getSaveFileNameWithExtension(const QString &title, const QString &path,
|
||||
const QString &fileFilter, const QString &extension);
|
||||
QString getSaveAsFileName(IFile *file);
|
||||
|
||||
QList<IFile *> saveModifiedFilesSilently(const QList<IFile *> &files);
|
||||
QList<IFile *> saveModifiedFiles(const QList<IFile *> &files,
|
||||
bool *cancelled = 0,
|
||||
const QString &message = QString(),
|
||||
const QString &alwaysSaveMessage = QString::null,
|
||||
bool *alwaysSave = 0);
|
||||
|
||||
signals:
|
||||
void currentFileChanged(const QString &filePath);
|
||||
|
||||
private slots:
|
||||
void fileDestroyed(QObject *obj);
|
||||
void checkForNewFileName();
|
||||
void checkForReload();
|
||||
void changedFile(const QString &file);
|
||||
void mainWindowActivated();
|
||||
void syncWithEditor(Core::IContext *context);
|
||||
|
||||
private:
|
||||
void addWatch(const QString &filename);
|
||||
void removeWatch(const QString &filename);
|
||||
void updateFileInfo(IFile *file);
|
||||
|
||||
QList<IFile *> saveModifiedFiles(const QList<IFile *> &files,
|
||||
bool *cancelled, bool silently,
|
||||
const QString &message,
|
||||
const QString &alwaysSaveMessage = QString::null,
|
||||
bool *alwaysSave = 0);
|
||||
|
||||
QMap<IFile*, FileInfo> m_managedFiles;
|
||||
|
||||
QStringList m_recentFiles;
|
||||
static const int m_maxRecentFiles = 7;
|
||||
|
||||
QString m_currentFile;
|
||||
|
||||
Internal::MainWindow *m_mainWindow;
|
||||
QFileSystemWatcher *m_fileWatcher;
|
||||
QList<QPointer<IFile> > m_changedFiles;
|
||||
bool m_blockActivated;
|
||||
};
|
||||
|
||||
/*! The FileChangeBlocker blocks all change notifications to all IFile * that
|
||||
match the given filename. And unblocks in the destructor.
|
||||
|
||||
To also reload the IFile in the destructor class set modifiedReload to true
|
||||
|
||||
*/
|
||||
class CORE_EXPORT FileChangeBlocker
|
||||
{
|
||||
public:
|
||||
FileChangeBlocker(const QString &fileName);
|
||||
~FileChangeBlocker();
|
||||
void setModifiedReload(bool reload);
|
||||
bool modifiedReload() const;
|
||||
private:
|
||||
QList<IFile *> m_files;
|
||||
bool m_reload;
|
||||
Q_DISABLE_COPY(FileChangeBlocker)
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif // FILEMANAGER_H
|
@ -1,86 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "findplaceholder.h"
|
||||
#include "modemanager.h"
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <QtGui/QVBoxLayout>
|
||||
|
||||
|
||||
using namespace Core;
|
||||
|
||||
FindToolBarPlaceHolder *FindToolBarPlaceHolder::m_current = 0;
|
||||
|
||||
FindToolBarPlaceHolder::FindToolBarPlaceHolder(QWidget *owner, QWidget *parent)
|
||||
: QWidget(parent), m_owner(owner), m_subWidget(0)
|
||||
{
|
||||
setLayout(new QVBoxLayout);
|
||||
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
|
||||
layout()->setMargin(0);
|
||||
ExtensionSystem::PluginManager::instance()->addObject(this);
|
||||
}
|
||||
|
||||
FindToolBarPlaceHolder::~FindToolBarPlaceHolder()
|
||||
{
|
||||
ExtensionSystem::PluginManager::instance()->removeObject(this);
|
||||
if (m_subWidget) {
|
||||
m_subWidget->setVisible(false);
|
||||
m_subWidget->setParent(0);
|
||||
}
|
||||
if (m_current == this)
|
||||
m_current = 0;
|
||||
}
|
||||
|
||||
QWidget *FindToolBarPlaceHolder::owner() const
|
||||
{
|
||||
return m_owner;
|
||||
}
|
||||
|
||||
void FindToolBarPlaceHolder::setWidget(QWidget *widget)
|
||||
{
|
||||
if (m_subWidget) {
|
||||
m_subWidget->setVisible(false);
|
||||
m_subWidget->setParent(0);
|
||||
}
|
||||
m_subWidget = widget;
|
||||
if (m_subWidget)
|
||||
layout()->addWidget(m_subWidget);
|
||||
}
|
||||
|
||||
FindToolBarPlaceHolder *FindToolBarPlaceHolder::getCurrent()
|
||||
{
|
||||
return m_current;
|
||||
}
|
||||
|
||||
void FindToolBarPlaceHolder::setCurrent(FindToolBarPlaceHolder *placeHolder)
|
||||
{
|
||||
m_current = placeHolder;
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef FINDPLACEHOLDER_H
|
||||
#define FINDPLACEHOLDER_H
|
||||
|
||||
#include "core_global.h"
|
||||
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class IMode;
|
||||
|
||||
class CORE_EXPORT FindToolBarPlaceHolder : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FindToolBarPlaceHolder(QWidget *owner, QWidget *parent = 0);
|
||||
~FindToolBarPlaceHolder();
|
||||
QWidget *owner() const;
|
||||
void setWidget(QWidget *widget);
|
||||
|
||||
static FindToolBarPlaceHolder *getCurrent();
|
||||
static void setCurrent(FindToolBarPlaceHolder *placeHolder);
|
||||
|
||||
private:
|
||||
QWidget *m_owner;
|
||||
QPointer<QWidget> m_subWidget;
|
||||
static FindToolBarPlaceHolder *m_current;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif // FINDPLACEHOLDER_H
|
@ -1,135 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "flowlayout.h"
|
||||
|
||||
using namespace Core::Internal;
|
||||
|
||||
FlowLayout::FlowLayout(QWidget *parent, int margin, int spacing)
|
||||
: QLayout(parent)
|
||||
{
|
||||
setMargin(margin);
|
||||
setSpacing(spacing);
|
||||
}
|
||||
|
||||
FlowLayout::FlowLayout(int spacing)
|
||||
{
|
||||
setSpacing(spacing);
|
||||
}
|
||||
|
||||
FlowLayout::~FlowLayout()
|
||||
{
|
||||
QLayoutItem *item;
|
||||
while ((item = takeAt(0)))
|
||||
delete item;
|
||||
}
|
||||
|
||||
void FlowLayout::addItem(QLayoutItem *item)
|
||||
{
|
||||
itemList.append(item);
|
||||
}
|
||||
|
||||
int FlowLayout::count() const
|
||||
{
|
||||
return itemList.size();
|
||||
}
|
||||
|
||||
QLayoutItem *FlowLayout::itemAt(int index) const
|
||||
{
|
||||
return itemList.value(index);
|
||||
}
|
||||
|
||||
QLayoutItem *FlowLayout::takeAt(int index)
|
||||
{
|
||||
if (index >= 0 && index < itemList.size())
|
||||
return itemList.takeAt(index);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
Qt::Orientations FlowLayout::expandingDirections() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FlowLayout::hasHeightForWidth() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int FlowLayout::heightForWidth(int width) const
|
||||
{
|
||||
int height = doLayout(QRect(0, 0, width, 0), true);
|
||||
return height;
|
||||
}
|
||||
|
||||
void FlowLayout::setGeometry(const QRect &rect)
|
||||
{
|
||||
QLayout::setGeometry(rect);
|
||||
doLayout(rect, false);
|
||||
}
|
||||
|
||||
QSize FlowLayout::sizeHint() const
|
||||
{
|
||||
return minimumSize();
|
||||
}
|
||||
|
||||
QSize FlowLayout::minimumSize() const
|
||||
{
|
||||
QSize size;
|
||||
foreach (QLayoutItem *item, itemList)
|
||||
size = size.expandedTo(item->minimumSize());
|
||||
|
||||
size += QSize(2 * margin(), 2 * margin());
|
||||
return size;
|
||||
}
|
||||
|
||||
int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
|
||||
{
|
||||
int x = rect.x();
|
||||
int y = rect.y();
|
||||
int lineHeight = 0;
|
||||
|
||||
foreach (QLayoutItem *item, itemList) {
|
||||
int nextX = x + item->sizeHint().width() + spacing();
|
||||
if (nextX - spacing() > rect.right() && lineHeight > 0) {
|
||||
x = rect.x();
|
||||
y = y + lineHeight + spacing();
|
||||
nextX = x + item->sizeHint().width() + spacing();
|
||||
lineHeight = 0;
|
||||
}
|
||||
|
||||
if (!testOnly)
|
||||
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
|
||||
|
||||
x = nextX;
|
||||
lineHeight = qMax(lineHeight, item->sizeHint().height());
|
||||
}
|
||||
return y + lineHeight - rect.y() + margin();
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef FLOWLAYOUT_H
|
||||
#define FLOWLAYOUT_H
|
||||
|
||||
#include <QLayout>
|
||||
#include <QRect>
|
||||
#include <QWidgetItem>
|
||||
|
||||
namespace Core {
|
||||
namespace Internal {
|
||||
|
||||
class FlowLayout : public QLayout
|
||||
{
|
||||
public:
|
||||
FlowLayout(QWidget *parent, int margin = 0, int spacing = -1);
|
||||
FlowLayout(int spacing = -1);
|
||||
~FlowLayout();
|
||||
|
||||
void addItem(QLayoutItem *item);
|
||||
Qt::Orientations expandingDirections() const;
|
||||
bool hasHeightForWidth() const;
|
||||
int heightForWidth(int) const;
|
||||
int count() const;
|
||||
QLayoutItem *itemAt(int index) const;
|
||||
QSize minimumSize() const;
|
||||
void setGeometry(const QRect &rect);
|
||||
QSize sizeHint() const;
|
||||
QLayoutItem *takeAt(int index);
|
||||
|
||||
private:
|
||||
int doLayout(const QRect &rect, bool testOnly) const;
|
||||
|
||||
QList<QLayoutItem *> itemList;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
#endif // FLOWLAYOUT_H
|
@ -1,55 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "inavigationwidgetfactory.h"
|
||||
|
||||
#include <QtGui/QKeySequence>
|
||||
|
||||
using namespace Core;
|
||||
|
||||
INavigationWidgetFactory::INavigationWidgetFactory()
|
||||
{
|
||||
}
|
||||
|
||||
INavigationWidgetFactory::~INavigationWidgetFactory()
|
||||
{
|
||||
}
|
||||
|
||||
QKeySequence INavigationWidgetFactory::activationSequence()
|
||||
{
|
||||
return QKeySequence();
|
||||
}
|
||||
|
||||
void INavigationWidgetFactory::saveSettings(int /* position */, QWidget * /* widget */)
|
||||
{
|
||||
}
|
||||
|
||||
void INavigationWidgetFactory::restoreSettings(int /* position */, QWidget * /* widget */)
|
||||
{
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef INAVIGATIONWIDGET_H
|
||||
#define INAVIGATIONWIDGET_H
|
||||
|
||||
#include <coreplugin/core_global.h>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QList>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QToolButton;
|
||||
class QKeySequence;
|
||||
class QWidget;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
|
||||
struct NavigationView
|
||||
{
|
||||
QWidget *widget;
|
||||
QList<QToolButton *> dockToolBarWidgets;
|
||||
};
|
||||
|
||||
class CORE_EXPORT INavigationWidgetFactory : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
INavigationWidgetFactory();
|
||||
virtual ~INavigationWidgetFactory();
|
||||
|
||||
virtual QString displayName() = 0;
|
||||
virtual QKeySequence activationSequence();
|
||||
// This design is not optimal, think about it again once we need to extend it
|
||||
// It could be implemented as returning an object which has both the widget
|
||||
// and the docktoolbar widgets
|
||||
// Similar to how IView
|
||||
virtual NavigationView createWidget() = 0;
|
||||
|
||||
// Read and store settings for the widget, created by this factory
|
||||
// and beeing at position position. (The position is important since
|
||||
// a certain type of widget could exist multiple times.)
|
||||
virtual void saveSettings(int position, QWidget *widget);
|
||||
virtual void restoreSettings(int position, QWidget *widget);
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif // INAVIGATIONWIDGET_H
|
@ -1,115 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef IOUTPUTPANE_H
|
||||
#define IOUTPUTPANE_H
|
||||
|
||||
#include "core_global.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QString>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QWidget;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
|
||||
class CORE_EXPORT IOutputPane : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
IOutputPane(QObject *parent = 0) : QObject(parent) {}
|
||||
virtual ~IOutputPane() {}
|
||||
|
||||
virtual QWidget *outputWidget(QWidget *parent) = 0;
|
||||
virtual QList<QWidget*> toolBarWidgets() const = 0;
|
||||
virtual QString name() const = 0;
|
||||
|
||||
// -1 don't show in statusBar
|
||||
// 100...0 show at front...end
|
||||
virtual int priorityInStatusBar() const = 0;
|
||||
|
||||
virtual void clearContents() = 0;
|
||||
virtual void visibilityChanged(bool visible) = 0;
|
||||
|
||||
// This function is called to give the outputwindow focus
|
||||
virtual void setFocus() = 0;
|
||||
// Wheter the outputpane has focus
|
||||
virtual bool hasFocus() = 0;
|
||||
// Wheter the outputpane can be focused at the moment.
|
||||
// (E.g. the search result window doesn't want to be focussed if the are no results.)
|
||||
virtual bool canFocus() = 0;
|
||||
|
||||
virtual bool canNavigate() = 0;
|
||||
virtual bool canNext() = 0;
|
||||
virtual bool canPrevious() = 0;
|
||||
virtual void goToNext() = 0;
|
||||
virtual void goToPrev() = 0;
|
||||
public slots:
|
||||
void popup()
|
||||
{
|
||||
popup(true);
|
||||
}
|
||||
void popup(bool withFocus)
|
||||
{
|
||||
emit showPage(withFocus);
|
||||
}
|
||||
|
||||
void hide()
|
||||
{
|
||||
emit hidePage();
|
||||
}
|
||||
|
||||
void toggle()
|
||||
{
|
||||
toggle(true);
|
||||
}
|
||||
|
||||
void toggle(bool withFocusIfShown)
|
||||
{
|
||||
emit togglePage(withFocusIfShown);
|
||||
}
|
||||
|
||||
void navigateStateChanged()
|
||||
{
|
||||
emit navigateStateUpdate();
|
||||
}
|
||||
|
||||
signals:
|
||||
void showPage(bool withFocus);
|
||||
void hidePage();
|
||||
void togglePage(bool withFocusIfShown);
|
||||
void navigateStateUpdate();
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif // IOUTPUTPANE_H
|
@ -1,534 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "navigationwidget.h"
|
||||
|
||||
#include "icore.h"
|
||||
#include "coreconstants.h"
|
||||
#include "inavigationwidgetfactory.h"
|
||||
#include "modemanager.h"
|
||||
#include "uniqueidmanager.h"
|
||||
#include "actionmanager/actionmanager.h"
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <utils/styledbar.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QSettings>
|
||||
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QHBoxLayout>
|
||||
#include <QtGui/QResizeEvent>
|
||||
#include <QtGui/QToolButton>
|
||||
#include <QtGui/QShortcut>
|
||||
|
||||
Q_DECLARE_METATYPE(Core::INavigationWidgetFactory *)
|
||||
|
||||
using namespace Core;
|
||||
using namespace Core::Internal;
|
||||
|
||||
NavigationWidgetPlaceHolder *NavigationWidgetPlaceHolder::m_current = 0;
|
||||
|
||||
NavigationWidgetPlaceHolder* NavigationWidgetPlaceHolder::current()
|
||||
{
|
||||
return m_current;
|
||||
}
|
||||
|
||||
NavigationWidgetPlaceHolder::NavigationWidgetPlaceHolder(Core::IMode *mode, QWidget *parent)
|
||||
:QWidget(parent), m_mode(mode)
|
||||
{
|
||||
setLayout(new QVBoxLayout);
|
||||
layout()->setMargin(0);
|
||||
connect(Core::ModeManager::instance(), SIGNAL(currentModeAboutToChange(Core::IMode *)),
|
||||
this, SLOT(currentModeAboutToChange(Core::IMode *)));
|
||||
}
|
||||
|
||||
NavigationWidgetPlaceHolder::~NavigationWidgetPlaceHolder()
|
||||
{
|
||||
if (m_current == this) {
|
||||
NavigationWidget::instance()->setParent(0);
|
||||
NavigationWidget::instance()->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationWidgetPlaceHolder::applyStoredSize(int width)
|
||||
{
|
||||
if (width) {
|
||||
QSplitter *splitter = qobject_cast<QSplitter *>(parentWidget());
|
||||
if (splitter) {
|
||||
// A splitter we need to resize the splitter sizes
|
||||
QList<int> sizes = splitter->sizes();
|
||||
int index = splitter->indexOf(this);
|
||||
int diff = width - sizes.at(index);
|
||||
int adjust = sizes.count() > 1 ? (diff / (sizes.count() - 1)) : 0;
|
||||
for (int i = 0; i < sizes.count(); ++i) {
|
||||
if (i != index)
|
||||
sizes[i] += adjust;
|
||||
}
|
||||
sizes[index]= width;
|
||||
splitter->setSizes(sizes);
|
||||
} else {
|
||||
QSize s = size();
|
||||
s.setWidth(width);
|
||||
resize(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function does work even though the order in which
|
||||
// the placeHolder get the signal is undefined.
|
||||
// It does ensure that after all PlaceHolders got the signal
|
||||
// m_current points to the current PlaceHolder, or zero if there
|
||||
// is no PlaceHolder in this mode
|
||||
// And that the parent of the NavigationWidget gets the correct parent
|
||||
void NavigationWidgetPlaceHolder::currentModeAboutToChange(Core::IMode *mode)
|
||||
{
|
||||
NavigationWidget *navigationWidget = NavigationWidget::instance();
|
||||
|
||||
if (m_current == this) {
|
||||
m_current = 0;
|
||||
navigationWidget->setParent(0);
|
||||
navigationWidget->hide();
|
||||
navigationWidget->placeHolderChanged(m_current);
|
||||
}
|
||||
if (m_mode == mode) {
|
||||
m_current = this;
|
||||
|
||||
int width = navigationWidget->storedWidth();
|
||||
|
||||
layout()->addWidget(navigationWidget);
|
||||
navigationWidget->show();
|
||||
|
||||
applyStoredSize(width);
|
||||
setVisible(navigationWidget->isShown());
|
||||
navigationWidget->placeHolderChanged(m_current);
|
||||
}
|
||||
}
|
||||
|
||||
NavigationWidget *NavigationWidget::m_instance = 0;
|
||||
|
||||
NavigationWidget::NavigationWidget(QAction *toggleSideBarAction)
|
||||
: m_shown(true),
|
||||
m_suppressed(false),
|
||||
m_width(0),
|
||||
m_toggleSideBarAction(toggleSideBarAction)
|
||||
{
|
||||
connect(ExtensionSystem::PluginManager::instance(), SIGNAL(objectAdded(QObject*)),
|
||||
this, SLOT(objectAdded(QObject*)));
|
||||
|
||||
setOrientation(Qt::Vertical);
|
||||
insertSubItem(0);
|
||||
m_instance = this;
|
||||
}
|
||||
|
||||
NavigationWidget::~NavigationWidget()
|
||||
{
|
||||
m_instance = 0;
|
||||
}
|
||||
|
||||
NavigationWidget *NavigationWidget::instance()
|
||||
{
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
int NavigationWidget::storedWidth()
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
void NavigationWidget::placeHolderChanged(NavigationWidgetPlaceHolder *holder)
|
||||
{
|
||||
m_toggleSideBarAction->setEnabled(holder);
|
||||
m_toggleSideBarAction->setChecked(holder && isShown());
|
||||
}
|
||||
|
||||
void NavigationWidget::resizeEvent(QResizeEvent *re)
|
||||
{
|
||||
if (m_width && re->size().width())
|
||||
m_width = re->size().width();
|
||||
MiniSplitter::resizeEvent(re);
|
||||
}
|
||||
|
||||
NavigationSubWidget *NavigationWidget::insertSubItem(int position)
|
||||
{
|
||||
NavigationSubWidget *nsw = new NavigationSubWidget(this);
|
||||
connect(nsw, SIGNAL(splitMe()), this, SLOT(splitSubWidget()));
|
||||
connect(nsw, SIGNAL(closeMe()), this, SLOT(closeSubWidget()));
|
||||
insertWidget(position, nsw);
|
||||
m_subWidgets.insert(position, nsw);
|
||||
return nsw;
|
||||
}
|
||||
|
||||
void NavigationWidget::activateSubWidget()
|
||||
{
|
||||
setShown(true);
|
||||
QShortcut *original = qobject_cast<QShortcut *>(sender());
|
||||
QString title = m_shortcutMap[original];
|
||||
|
||||
foreach (NavigationSubWidget *subWidget, m_subWidgets)
|
||||
if (subWidget->factory()->displayName() == title) {
|
||||
subWidget->setFocusWidget();
|
||||
return;
|
||||
}
|
||||
|
||||
m_subWidgets.first()->setFactory(title);
|
||||
m_subWidgets.first()->setFocusWidget();
|
||||
}
|
||||
|
||||
void NavigationWidget::splitSubWidget()
|
||||
{
|
||||
NavigationSubWidget *original = qobject_cast<NavigationSubWidget *>(sender());
|
||||
int pos = indexOf(original) + 1;
|
||||
NavigationSubWidget *newnsw = insertSubItem(pos);
|
||||
newnsw->setFactory(original->factory());
|
||||
}
|
||||
|
||||
void NavigationWidget::closeSubWidget()
|
||||
{
|
||||
if (m_subWidgets.count() != 1) {
|
||||
NavigationSubWidget *subWidget = qobject_cast<NavigationSubWidget *>(sender());
|
||||
m_subWidgets.removeOne(subWidget);
|
||||
subWidget->hide();
|
||||
subWidget->deleteLater();
|
||||
} else {
|
||||
setShown(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void NavigationWidget::saveSettings(QSettings *settings)
|
||||
{
|
||||
QStringList views;
|
||||
//for (int i=0; i<m_subWidgets.count(); ++i) {
|
||||
// views.append(m_subWidgets.at(i)->factory()->displayName());
|
||||
//}
|
||||
settings->setValue("Navigation/Views", views);
|
||||
settings->setValue("Navigation/Visible", isShown());
|
||||
settings->setValue("Navigation/VerticalPosition", saveState());
|
||||
settings->setValue("Navigation/Width", m_width);
|
||||
|
||||
for (int i=0; i<m_subWidgets.count(); ++i)
|
||||
m_subWidgets.at(i)->saveSettings(i);
|
||||
}
|
||||
|
||||
void NavigationWidget::restoreSettings(QSettings *settings)
|
||||
{
|
||||
int version = settings->value("Navigation/Version", 1).toInt();
|
||||
QStringList views = settings->value("Navigation/Views").toStringList();
|
||||
|
||||
bool restoreSplitterState = true;
|
||||
if (version == 1) {
|
||||
if (views.isEmpty())
|
||||
views += "Projects";
|
||||
if (!views.contains("Open Documents")) {
|
||||
views += "Open Documents";
|
||||
restoreSplitterState = false;
|
||||
}
|
||||
settings->setValue("Navigation/Version", 2);
|
||||
}
|
||||
|
||||
for (int i=0; i<views.count()-1; ++i) {
|
||||
insertSubItem(0);
|
||||
}
|
||||
for (int i=0; i<views.count(); ++i) {
|
||||
const QString &view = views.at(i);
|
||||
NavigationSubWidget *nsw = m_subWidgets.at(i);
|
||||
nsw->setFactory(view);
|
||||
}
|
||||
|
||||
if (settings->contains("Navigation/Visible")) {
|
||||
setShown(settings->value("Navigation/Visible").toBool());
|
||||
} else {
|
||||
setShown(true);
|
||||
}
|
||||
|
||||
if (restoreSplitterState && settings->contains("Navigation/VerticalPosition")) {
|
||||
restoreState(settings->value("Navigation/VerticalPosition").toByteArray());
|
||||
} else {
|
||||
QList<int> sizes;
|
||||
sizes += 256;
|
||||
for (int i = views.size()-1; i > 0; --i)
|
||||
sizes.prepend(512);
|
||||
setSizes(sizes);
|
||||
}
|
||||
|
||||
if (settings->contains("Navigation/Width")) {
|
||||
m_width = settings->value("Navigation/Width").toInt();
|
||||
if (!m_width)
|
||||
m_width = 240;
|
||||
} else {
|
||||
m_width = 240; //pixel
|
||||
}
|
||||
// Apply
|
||||
if (NavigationWidgetPlaceHolder::m_current) {
|
||||
NavigationWidgetPlaceHolder::m_current->applyStoredSize(m_width);
|
||||
}
|
||||
|
||||
for (int i=0; i<m_subWidgets.count(); ++i)
|
||||
m_subWidgets.at(i)->restoreSettings(i);
|
||||
}
|
||||
|
||||
void NavigationWidget::setShown(bool b)
|
||||
{
|
||||
if (m_shown == b)
|
||||
return;
|
||||
m_shown = b;
|
||||
if (NavigationWidgetPlaceHolder::m_current) {
|
||||
NavigationWidgetPlaceHolder::m_current->setVisible(m_shown && !m_suppressed);
|
||||
m_toggleSideBarAction->setChecked(m_shown);
|
||||
} else {
|
||||
m_toggleSideBarAction->setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool NavigationWidget::isShown() const
|
||||
{
|
||||
return m_shown;
|
||||
}
|
||||
|
||||
bool NavigationWidget::isSuppressed() const
|
||||
{
|
||||
return m_suppressed;
|
||||
}
|
||||
|
||||
void NavigationWidget::setSuppressed(bool b)
|
||||
{
|
||||
if (m_suppressed == b)
|
||||
return;
|
||||
m_suppressed = b;
|
||||
if (NavigationWidgetPlaceHolder::m_current)
|
||||
NavigationWidgetPlaceHolder::m_current->setVisible(m_shown && !m_suppressed);
|
||||
}
|
||||
|
||||
void NavigationWidget::objectAdded(QObject * obj)
|
||||
{
|
||||
INavigationWidgetFactory *factory = Aggregation::query<INavigationWidgetFactory>(obj);
|
||||
if (!factory)
|
||||
return;
|
||||
|
||||
ICore *core = ICore::instance();
|
||||
ActionManager *am = core->actionManager();
|
||||
QList<int> navicontext = QList<int>() << core->uniqueIDManager()->
|
||||
uniqueIdentifier(Core::Constants::C_NAVIGATION_PANE);
|
||||
|
||||
QString displayName = factory->displayName();
|
||||
QShortcut *shortcut = new QShortcut(this);
|
||||
shortcut->setWhatsThis(tr("Activate %1 Pane").arg(displayName));
|
||||
Core::Command *cmd = am->registerShortcut(shortcut,
|
||||
QLatin1String("QtCreator.Sidebar.") + displayName, navicontext);
|
||||
cmd->setDefaultKeySequence(factory->activationSequence());
|
||||
connect(shortcut, SIGNAL(activated()), this, SLOT(activateSubWidget()));
|
||||
|
||||
m_shortcutMap.insert(shortcut, displayName);
|
||||
m_commandMap.insert(displayName, cmd);
|
||||
}
|
||||
|
||||
////
|
||||
// NavigationSubWidget
|
||||
////
|
||||
|
||||
|
||||
NavigationSubWidget::NavigationSubWidget(NavigationWidget *parentWidget)
|
||||
: m_parentWidget(parentWidget)
|
||||
{
|
||||
connect(ExtensionSystem::PluginManager::instance(), SIGNAL(objectAdded(QObject*)),
|
||||
this, SLOT(objectAdded(QObject*)));
|
||||
connect(ExtensionSystem::PluginManager::instance(), SIGNAL(aboutToRemoveObject(QObject*)),
|
||||
this, SLOT(aboutToRemoveObject(QObject*)));
|
||||
|
||||
m_navigationComboBox = new NavComboBox(this);
|
||||
m_navigationComboBox->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
|
||||
m_navigationComboBox->setMinimumContentsLength(0);
|
||||
m_navigationWidget = 0;
|
||||
|
||||
m_toolBar = new Utils::StyledBar(this);
|
||||
QHBoxLayout *toolBarLayout = new QHBoxLayout;
|
||||
toolBarLayout->setMargin(0);
|
||||
toolBarLayout->setSpacing(0);
|
||||
m_toolBar->setLayout(toolBarLayout);
|
||||
toolBarLayout->addWidget(m_navigationComboBox);
|
||||
|
||||
QToolButton *splitAction = new QToolButton();
|
||||
splitAction->setIcon(QIcon(":/core/images/splitbutton_horizontal.png"));
|
||||
splitAction->setToolTip(tr("Split"));
|
||||
QToolButton *close = new QToolButton();
|
||||
close->setIcon(QIcon(":/core/images/closebutton.png"));
|
||||
close->setToolTip(tr("Close"));
|
||||
|
||||
toolBarLayout->addWidget(splitAction);
|
||||
toolBarLayout->addWidget(close);
|
||||
|
||||
QVBoxLayout *lay = new QVBoxLayout();
|
||||
lay->setMargin(0);
|
||||
lay->setSpacing(0);
|
||||
setLayout(lay);
|
||||
lay->addWidget(m_toolBar);
|
||||
|
||||
connect(splitAction, SIGNAL(clicked()), this, SIGNAL(splitMe()));
|
||||
connect(close, SIGNAL(clicked()), this, SIGNAL(closeMe()));
|
||||
connect(m_navigationComboBox, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(setCurrentIndex(int)));
|
||||
|
||||
foreach (INavigationWidgetFactory *factory, ExtensionSystem::PluginManager::instance()->getObjects<INavigationWidgetFactory>()) {
|
||||
QVariant v;
|
||||
v.setValue(factory);
|
||||
m_navigationComboBox->addItem(factory->displayName(), v);
|
||||
}
|
||||
}
|
||||
|
||||
NavigationSubWidget::~NavigationSubWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void NavigationSubWidget::setCurrentIndex(int index)
|
||||
{
|
||||
// Remove toolbutton
|
||||
foreach (QWidget *w, m_additionalToolBarWidgets)
|
||||
delete w;
|
||||
|
||||
// Remove old Widget
|
||||
delete m_navigationWidget;
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
// Get new stuff
|
||||
INavigationWidgetFactory *factory = m_navigationComboBox->itemData(index).value<INavigationWidgetFactory *>();
|
||||
NavigationView n = factory->createWidget();
|
||||
m_navigationWidget = n.widget;
|
||||
layout()->addWidget(m_navigationWidget);
|
||||
|
||||
// Add Toolbutton
|
||||
m_additionalToolBarWidgets = n.dockToolBarWidgets;
|
||||
QHBoxLayout *layout = qobject_cast<QHBoxLayout *>(m_toolBar->layout());
|
||||
foreach (QToolButton *w, m_additionalToolBarWidgets) {
|
||||
layout->insertWidget(layout->count()-2, w);
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationSubWidget::setFocusWidget()
|
||||
{
|
||||
if (m_navigationWidget)
|
||||
m_navigationWidget->setFocus();
|
||||
}
|
||||
|
||||
void NavigationSubWidget::objectAdded(QObject * obj)
|
||||
{
|
||||
INavigationWidgetFactory *factory = Aggregation::query<INavigationWidgetFactory>(obj);
|
||||
if (!factory)
|
||||
return;
|
||||
|
||||
QVariant v;
|
||||
v.setValue(factory);
|
||||
m_navigationComboBox->addItem(factory->displayName(), v);
|
||||
//qDebug()<<"added factory :"<<factory<<m_navigationComboBox->findData(v);
|
||||
}
|
||||
|
||||
void NavigationSubWidget::aboutToRemoveObject(QObject *obj)
|
||||
{
|
||||
INavigationWidgetFactory *factory = Aggregation::query<INavigationWidgetFactory>(obj);
|
||||
if (!factory)
|
||||
return;
|
||||
QVariant v;
|
||||
v.setValue(factory);
|
||||
int index = m_navigationComboBox->findData(v);
|
||||
if (index == -1) {
|
||||
qDebug()<<"factory not found not removing" << factory;
|
||||
return;
|
||||
}
|
||||
m_navigationComboBox->removeItem(index);
|
||||
}
|
||||
|
||||
void NavigationSubWidget::setFactory(INavigationWidgetFactory *factory)
|
||||
{
|
||||
QVariant v;
|
||||
v.setValue(factory);
|
||||
int index = m_navigationComboBox->findData(v);
|
||||
if (index == -1)
|
||||
return;
|
||||
m_navigationComboBox->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
void NavigationSubWidget::setFactory(const QString &name)
|
||||
{
|
||||
for (int i = 0; i < m_navigationComboBox->count(); ++i) {
|
||||
INavigationWidgetFactory *factory =
|
||||
m_navigationComboBox->itemData(i).value<INavigationWidgetFactory *>();
|
||||
if (factory->displayName() == name)
|
||||
m_navigationComboBox->setCurrentIndex(i);
|
||||
}
|
||||
}
|
||||
|
||||
INavigationWidgetFactory *NavigationSubWidget::factory()
|
||||
{
|
||||
int index = m_navigationComboBox->currentIndex();
|
||||
if (index == -1)
|
||||
return 0;
|
||||
return m_navigationComboBox->itemData(index).value<INavigationWidgetFactory *>();
|
||||
}
|
||||
|
||||
void NavigationSubWidget::saveSettings(int position)
|
||||
{
|
||||
//factory()->saveSettings(position, m_navigationWidget);
|
||||
}
|
||||
|
||||
void NavigationSubWidget::restoreSettings(int position)
|
||||
{
|
||||
//factory()->restoreSettings(position, m_navigationWidget);
|
||||
}
|
||||
|
||||
Core::Command *NavigationSubWidget::command(const QString &title) const
|
||||
{
|
||||
const QHash<QString, Core::Command*> commandMap = m_parentWidget->commandMap();
|
||||
QHash<QString, Core::Command*>::const_iterator r = commandMap.find(title);
|
||||
if (r != commandMap.end())
|
||||
return r.value();
|
||||
return 0;
|
||||
}
|
||||
|
||||
NavComboBox::NavComboBox(NavigationSubWidget *navSubWidget)
|
||||
: m_navSubWidget(navSubWidget)
|
||||
{
|
||||
}
|
||||
|
||||
bool NavComboBox::event(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::ToolTip) {
|
||||
QString txt = currentText();
|
||||
Core::Command *cmd = m_navSubWidget->command(txt);
|
||||
if (cmd) {
|
||||
txt = tr("Activate %1").arg(txt);
|
||||
setToolTip(cmd->stringWithAppendedShortcut(txt));
|
||||
} else {
|
||||
setToolTip(txt);
|
||||
}
|
||||
}
|
||||
return QComboBox::event(e);
|
||||
}
|
@ -1,172 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef NAVIGATIONWIDGET_H
|
||||
#define NAVIGATIONWIDGET_H
|
||||
|
||||
#include <coreplugin/minisplitter.h>
|
||||
|
||||
#include <QtGui/QComboBox>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QSettings;
|
||||
class QShortcut;
|
||||
class QToolButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Utils {
|
||||
class StyledBar;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
class INavigationWidgetFactory;
|
||||
class IMode;
|
||||
class Command;
|
||||
|
||||
namespace Internal {
|
||||
class NavigationWidget;
|
||||
}
|
||||
|
||||
class CORE_EXPORT NavigationWidgetPlaceHolder : public QWidget
|
||||
{
|
||||
friend class Core::Internal::NavigationWidget;
|
||||
Q_OBJECT
|
||||
public:
|
||||
NavigationWidgetPlaceHolder(Core::IMode *mode, QWidget *parent = 0);
|
||||
~NavigationWidgetPlaceHolder();
|
||||
static NavigationWidgetPlaceHolder* current();
|
||||
void applyStoredSize(int width);
|
||||
private slots:
|
||||
void currentModeAboutToChange(Core::IMode *);
|
||||
private:
|
||||
Core::IMode *m_mode;
|
||||
static NavigationWidgetPlaceHolder* m_current;
|
||||
};
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class NavigationSubWidget;
|
||||
|
||||
class NavigationWidget : public MiniSplitter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NavigationWidget(QAction *toggleSideBarAction);
|
||||
~NavigationWidget();
|
||||
|
||||
void saveSettings(QSettings *settings);
|
||||
void restoreSettings(QSettings *settings);
|
||||
|
||||
bool isShown() const;
|
||||
void setShown(bool b);
|
||||
|
||||
bool isSuppressed() const;
|
||||
void setSuppressed(bool b);
|
||||
|
||||
static NavigationWidget* instance();
|
||||
|
||||
int storedWidth();
|
||||
|
||||
// Called from the place holders
|
||||
void placeHolderChanged(NavigationWidgetPlaceHolder *holder);
|
||||
|
||||
QHash<QString, Core::Command*> commandMap() const { return m_commandMap; }
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *);
|
||||
private slots:
|
||||
void objectAdded(QObject*);
|
||||
void activateSubWidget();
|
||||
void splitSubWidget();
|
||||
void closeSubWidget();
|
||||
|
||||
private:
|
||||
NavigationSubWidget *insertSubItem(int position);
|
||||
QList<NavigationSubWidget *> m_subWidgets;
|
||||
QHash<QShortcut *, QString> m_shortcutMap;
|
||||
QHash<QString, Core::Command*> m_commandMap;
|
||||
bool m_shown;
|
||||
bool m_suppressed;
|
||||
int m_width;
|
||||
static NavigationWidget* m_instance;
|
||||
QAction *m_toggleSideBarAction;
|
||||
};
|
||||
|
||||
class NavigationSubWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NavigationSubWidget(NavigationWidget *parentWidget);
|
||||
virtual ~NavigationSubWidget();
|
||||
|
||||
INavigationWidgetFactory *factory();
|
||||
void setFactory(INavigationWidgetFactory *factory);
|
||||
void setFactory(const QString &name);
|
||||
void setFocusWidget();
|
||||
|
||||
void saveSettings(int position);
|
||||
void restoreSettings(int position);
|
||||
|
||||
Core::Command *command(const QString &title) const;
|
||||
|
||||
signals:
|
||||
void splitMe();
|
||||
void closeMe();
|
||||
|
||||
private slots:
|
||||
void objectAdded(QObject*);
|
||||
void aboutToRemoveObject(QObject*);
|
||||
void setCurrentIndex(int);
|
||||
|
||||
private:
|
||||
NavigationWidget *m_parentWidget;
|
||||
QComboBox *m_navigationComboBox;
|
||||
QWidget *m_navigationWidget;
|
||||
Utils::StyledBar *m_toolBar;
|
||||
QList<QToolButton *> m_additionalToolBarWidgets;
|
||||
};
|
||||
|
||||
class NavComboBox : public QComboBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NavComboBox(NavigationSubWidget *navSubWidget);
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event);
|
||||
|
||||
private:
|
||||
NavigationSubWidget *m_navSubWidget;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
#endif // NAVIGATIONWIDGET_H
|
@ -1,614 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "outputpane.h"
|
||||
#include "coreconstants.h"
|
||||
#include "icore.h"
|
||||
#include "ioutputpane.h"
|
||||
#include "mainwindow.h"
|
||||
#include "modemanager.h"
|
||||
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/findplaceholder.h>
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <utils/styledbar.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QComboBox>
|
||||
#include <QtGui/QFocusEvent>
|
||||
#include <QtGui/QHBoxLayout>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtGui/QToolButton>
|
||||
#include <QtGui/QStackedWidget>
|
||||
|
||||
using namespace Core;
|
||||
using namespace Core::Internal;
|
||||
|
||||
namespace Core {
|
||||
namespace Internal {
|
||||
|
||||
class OutputPaneToggleButton : public QPushButton
|
||||
{
|
||||
public:
|
||||
OutputPaneToggleButton(int number, const QString &text, QWidget *parent = 0);
|
||||
QSize sizeHint() const;
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
private:
|
||||
QString m_number;
|
||||
QString m_text;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
OutputPanePlaceHolder *OutputPanePlaceHolder::m_current = 0;
|
||||
|
||||
OutputPanePlaceHolder::OutputPanePlaceHolder(Core::IMode *mode, QWidget *parent)
|
||||
: QWidget(parent), m_mode(mode), m_closeable(true)
|
||||
{
|
||||
setVisible(false);
|
||||
setLayout(new QVBoxLayout);
|
||||
QSizePolicy sp;
|
||||
sp.setHorizontalPolicy(QSizePolicy::Preferred);
|
||||
sp.setVerticalPolicy(QSizePolicy::Preferred);
|
||||
sp.setHorizontalStretch(0);
|
||||
setSizePolicy(sp);
|
||||
layout()->setMargin(0);
|
||||
connect(Core::ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode *)),
|
||||
this, SLOT(currentModeChanged(Core::IMode *)));
|
||||
}
|
||||
|
||||
OutputPanePlaceHolder::~OutputPanePlaceHolder()
|
||||
{
|
||||
if (m_current == this) {
|
||||
OutputPaneManager::instance()->setParent(0);
|
||||
OutputPaneManager::instance()->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void OutputPanePlaceHolder::setCloseable(bool b)
|
||||
{
|
||||
m_closeable = b;
|
||||
}
|
||||
|
||||
bool OutputPanePlaceHolder::closeable()
|
||||
{
|
||||
return m_closeable;
|
||||
}
|
||||
|
||||
void OutputPanePlaceHolder::currentModeChanged(Core::IMode *mode)
|
||||
{
|
||||
if (m_current == this) {
|
||||
m_current = 0;
|
||||
OutputPaneManager::instance()->setParent(0);
|
||||
OutputPaneManager::instance()->hide();
|
||||
OutputPaneManager::instance()->updateStatusButtons(false);
|
||||
}
|
||||
if (m_mode == mode) {
|
||||
m_current = this;
|
||||
layout()->addWidget(OutputPaneManager::instance());
|
||||
OutputPaneManager::instance()->show();
|
||||
OutputPaneManager::instance()->updateStatusButtons(isVisible());
|
||||
OutputPaneManager::instance()->setCloseable(m_closeable);
|
||||
}
|
||||
}
|
||||
|
||||
////
|
||||
// OutputPaneManager
|
||||
////
|
||||
|
||||
static OutputPaneManager *m_instance = 0;
|
||||
|
||||
void OutputPaneManager::create()
|
||||
{
|
||||
m_instance = new OutputPaneManager;
|
||||
}
|
||||
|
||||
void OutputPaneManager::destroy()
|
||||
{
|
||||
delete m_instance;
|
||||
m_instance = 0;
|
||||
}
|
||||
|
||||
OutputPaneManager *OutputPaneManager::instance()
|
||||
{
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
void OutputPaneManager::updateStatusButtons(bool visible)
|
||||
{
|
||||
int idx = m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt();
|
||||
if (m_buttons.value(idx))
|
||||
m_buttons.value(idx)->setChecked(visible);
|
||||
}
|
||||
|
||||
OutputPaneManager::OutputPaneManager(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
m_widgetComboBox(new QComboBox),
|
||||
m_clearButton(new QToolButton),
|
||||
m_closeButton(new QToolButton),
|
||||
m_nextAction(0),
|
||||
m_prevAction(0),
|
||||
m_lastIndex(-1),
|
||||
m_outputWidgetPane(new QStackedWidget),
|
||||
m_opToolBarWidgets(new QStackedWidget)
|
||||
{
|
||||
setWindowTitle(tr("Output"));
|
||||
connect(m_widgetComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changePage()));
|
||||
|
||||
m_clearButton->setIcon(QIcon(Constants::ICON_CLEAN_PANE));
|
||||
m_clearButton->setToolTip(tr("Clear"));
|
||||
connect(m_clearButton, SIGNAL(clicked()), this, SLOT(clearPage()));
|
||||
|
||||
m_nextAction = new QAction(this);
|
||||
m_nextAction->setIcon(QIcon(":/core/images/next.png"));
|
||||
m_nextAction->setText(tr("Next Item"));
|
||||
connect(m_nextAction, SIGNAL(triggered()), this, SLOT(slotNext()));
|
||||
|
||||
m_prevAction = new QAction(this);
|
||||
m_prevAction->setIcon(QIcon(":/core/images/prev.png"));
|
||||
m_prevAction->setText(tr("Previous Item"));
|
||||
connect(m_prevAction, SIGNAL(triggered()), this, SLOT(slotPrev()));
|
||||
|
||||
m_closeButton->setIcon(QIcon(":/core/images/closebutton.png"));
|
||||
connect(m_closeButton, SIGNAL(clicked()), this, SLOT(slotHide()));
|
||||
|
||||
QVBoxLayout *mainlayout = new QVBoxLayout;
|
||||
mainlayout->setSpacing(0);
|
||||
mainlayout->setMargin(0);
|
||||
m_toolBar = new Utils::StyledBar;
|
||||
QHBoxLayout *toolLayout = new QHBoxLayout(m_toolBar);
|
||||
toolLayout->setMargin(0);
|
||||
toolLayout->setSpacing(0);
|
||||
toolLayout->addWidget(m_widgetComboBox);
|
||||
toolLayout->addWidget(m_clearButton);
|
||||
m_prevToolButton = new QToolButton;
|
||||
toolLayout->addWidget(m_prevToolButton);
|
||||
m_nextToolButton = new QToolButton;
|
||||
toolLayout->addWidget(m_nextToolButton);
|
||||
toolLayout->addWidget(m_opToolBarWidgets);
|
||||
toolLayout->addWidget(m_closeButton);
|
||||
mainlayout->addWidget(m_toolBar);
|
||||
mainlayout->addWidget(m_outputWidgetPane, 10);
|
||||
mainlayout->addWidget(new Core::FindToolBarPlaceHolder(this));
|
||||
setLayout(mainlayout);
|
||||
|
||||
m_buttonsWidget = new QWidget;
|
||||
m_buttonsWidget->setLayout(new QHBoxLayout);
|
||||
m_buttonsWidget->layout()->setContentsMargins(5,0,0,0);
|
||||
#ifdef Q_WS_MAC
|
||||
m_buttonsWidget->layout()->setSpacing(16);
|
||||
#else
|
||||
m_buttonsWidget->layout()->setSpacing(4);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
OutputPaneManager::~OutputPaneManager()
|
||||
{
|
||||
}
|
||||
|
||||
QWidget *OutputPaneManager::buttonsWidget()
|
||||
{
|
||||
return m_buttonsWidget;
|
||||
}
|
||||
|
||||
// Return shortcut as Ctrl+<number>
|
||||
static inline int paneShortCut(int modifier, int number)
|
||||
{
|
||||
return modifier | (Qt::Key_0 + number);
|
||||
}
|
||||
|
||||
void OutputPaneManager::init()
|
||||
{
|
||||
ActionManager *am = Core::ICore::instance()->actionManager();
|
||||
ActionContainer *mwindow = am->actionContainer(Constants::M_WINDOW);
|
||||
QList<int> globalcontext;
|
||||
globalcontext.append(Core::Constants::C_GLOBAL_ID);
|
||||
|
||||
// Window->Output Panes
|
||||
ActionContainer *mpanes = am->createMenu(Constants::M_WINDOW_PANES);
|
||||
mwindow->addMenu(mpanes, Constants::G_WINDOW_PANES);
|
||||
mpanes->menu()->setTitle(tr("Output &Panes"));
|
||||
mpanes->appendGroup("Coreplugin.OutputPane.ActionsGroup");
|
||||
mpanes->appendGroup("Coreplugin.OutputPane.PanesGroup");
|
||||
|
||||
Core::Command *cmd;
|
||||
|
||||
cmd = am->registerAction(m_prevAction, "Coreplugin.OutputPane.previtem", globalcontext);
|
||||
cmd->setDefaultKeySequence(QKeySequence("Shift+F6"));
|
||||
m_prevToolButton->setDefaultAction(cmd->action());
|
||||
mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup");
|
||||
|
||||
cmd = am->registerAction(m_nextAction, "Coreplugin.OutputPane.nextitem", globalcontext);
|
||||
m_nextToolButton->setDefaultAction(cmd->action());
|
||||
cmd->setDefaultKeySequence(QKeySequence("F6"));
|
||||
mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup");
|
||||
|
||||
QAction *sep = new QAction(this);
|
||||
sep->setSeparator(true);
|
||||
cmd = am->registerAction(sep, QLatin1String("Coreplugin.OutputPane.Sep"), globalcontext);
|
||||
mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup");
|
||||
|
||||
QList<IOutputPane*> panes = ExtensionSystem::PluginManager::instance()
|
||||
->getObjects<IOutputPane>();
|
||||
QMultiMap<int, IOutputPane*> sorted;
|
||||
foreach (IOutputPane* outPane, panes)
|
||||
sorted.insertMulti(outPane->priorityInStatusBar(), outPane);
|
||||
|
||||
QMultiMap<int, IOutputPane*>::const_iterator it, begin;
|
||||
begin = sorted.constBegin();
|
||||
it = sorted.constEnd();
|
||||
int shortcutNumber = 1;
|
||||
do {
|
||||
--it;
|
||||
IOutputPane* outPane = it.value();
|
||||
const int idx = m_outputWidgetPane->addWidget(outPane->outputWidget(this));
|
||||
|
||||
m_pageMap.insert(idx, outPane);
|
||||
connect(outPane, SIGNAL(showPage(bool)), this, SLOT(showPage(bool)));
|
||||
connect(outPane, SIGNAL(hidePage()), this, SLOT(slotHide()));
|
||||
connect(outPane, SIGNAL(togglePage(bool)), this, SLOT(togglePage(bool)));
|
||||
connect(outPane, SIGNAL(navigateStateUpdate()), this, SLOT(updateNavigateState()));
|
||||
|
||||
QWidget *toolButtonsContainer = new QWidget(m_opToolBarWidgets);
|
||||
QHBoxLayout *toolButtonsLayout = new QHBoxLayout;
|
||||
toolButtonsLayout->setMargin(0);
|
||||
toolButtonsLayout->setSpacing(0);
|
||||
foreach (QWidget *toolButton, outPane->toolBarWidgets())
|
||||
toolButtonsLayout->addWidget(toolButton);
|
||||
toolButtonsLayout->addStretch(5);
|
||||
toolButtonsContainer->setLayout(toolButtonsLayout);
|
||||
|
||||
m_opToolBarWidgets->addWidget(toolButtonsContainer);
|
||||
|
||||
QString actionId = QString("QtCreator.Pane.%1").arg(outPane->name().simplified());
|
||||
actionId.remove(QLatin1Char(' '));
|
||||
QAction *action = new QAction(outPane->name(), this);
|
||||
|
||||
Command *cmd = am->registerAction(action, actionId, QList<int>() << Constants::C_GLOBAL_ID);
|
||||
if (outPane->priorityInStatusBar() != -1) {
|
||||
#ifdef Q_WS_MAC
|
||||
cmd->setDefaultKeySequence(QKeySequence(paneShortCut(Qt::CTRL, shortcutNumber)));
|
||||
#else
|
||||
cmd->setDefaultKeySequence(QKeySequence(paneShortCut(Qt::ALT, shortcutNumber)));
|
||||
#endif
|
||||
}
|
||||
mpanes->addAction(cmd, "Coreplugin.OutputPane.PanesGroup");
|
||||
m_actions.insert(cmd->action(), idx);
|
||||
|
||||
// TODO priority -1
|
||||
if (outPane->priorityInStatusBar() != -1) {
|
||||
QPushButton *button = new OutputPaneToggleButton(shortcutNumber, outPane->name());
|
||||
++shortcutNumber;
|
||||
m_buttonsWidget->layout()->addWidget(button);
|
||||
connect(button, SIGNAL(clicked()), this, SLOT(buttonTriggered()));
|
||||
m_buttons.insert(idx, button);
|
||||
}
|
||||
|
||||
// Now add the entry to the combobox, since the first item we add sets the currentIndex, thus we need to be set up for that
|
||||
m_widgetComboBox->addItem(outPane->name(), idx);
|
||||
|
||||
connect(cmd->action(), SIGNAL(triggered()), this, SLOT(shortcutTriggered()));
|
||||
connect(cmd->action(), SIGNAL(changed()), this, SLOT(updateToolTip()));
|
||||
} while (it != begin);
|
||||
|
||||
changePage();
|
||||
}
|
||||
|
||||
void OutputPaneManager::shortcutTriggered()
|
||||
{
|
||||
QAction *action = qobject_cast<QAction*>(sender());
|
||||
if (action && m_actions.contains(action)) {
|
||||
int idx = m_actions.value(action);
|
||||
Core::IOutputPane *outputPane = m_pageMap.value(idx);
|
||||
// Now check the special case, the output window is already visible,
|
||||
// we are already on that page
|
||||
// but the outputpane doesn't have focus
|
||||
// then just give it focus
|
||||
// else do the same as clicking on the button does
|
||||
if (OutputPanePlaceHolder::m_current
|
||||
&& OutputPanePlaceHolder::m_current->isVisible()
|
||||
&& m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt() == idx) {
|
||||
if (!outputPane->hasFocus() && outputPane->canFocus())
|
||||
outputPane->setFocus();
|
||||
else
|
||||
slotHide();
|
||||
} else {
|
||||
outputPane->popup(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OutputPaneManager::buttonTriggered()
|
||||
{
|
||||
QPushButton *button = qobject_cast<QPushButton *>(sender());
|
||||
QMap<int, QPushButton *>::const_iterator it, end;
|
||||
end = m_buttons.constEnd();
|
||||
for (it = m_buttons.begin(); it != end; ++it) {
|
||||
if (it.value() == button)
|
||||
break;
|
||||
}
|
||||
int idx = it.key();
|
||||
|
||||
if (m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt() == idx &&
|
||||
OutputPanePlaceHolder::m_current &&
|
||||
OutputPanePlaceHolder::m_current->isVisible() &&
|
||||
OutputPanePlaceHolder::m_current->closeable()) {
|
||||
// we should toggle and the page is already visible and we are actually closeable
|
||||
slotHide();
|
||||
} else {
|
||||
showPage(idx, true);
|
||||
}
|
||||
}
|
||||
|
||||
void OutputPaneManager::updateToolTip()
|
||||
{
|
||||
QAction *action = qobject_cast<QAction*>(sender());
|
||||
if (action) {
|
||||
QPushButton *button = m_buttons.value(m_actions.value(action));
|
||||
if (button)
|
||||
button->setToolTip(action->toolTip());
|
||||
}
|
||||
}
|
||||
|
||||
void OutputPaneManager::slotNext()
|
||||
{
|
||||
int idx = m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt();
|
||||
ensurePageVisible(idx);
|
||||
IOutputPane *out = m_pageMap.value(idx);
|
||||
if (out->canNext())
|
||||
out->goToNext();
|
||||
}
|
||||
|
||||
void OutputPaneManager::slotPrev()
|
||||
{
|
||||
int idx = m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt();
|
||||
ensurePageVisible(idx);
|
||||
IOutputPane *out = m_pageMap.value(idx);
|
||||
if (out->canPrevious())
|
||||
out->goToPrev();
|
||||
}
|
||||
|
||||
void OutputPaneManager::slotHide()
|
||||
{
|
||||
if (OutputPanePlaceHolder::m_current) {
|
||||
OutputPanePlaceHolder::m_current->setVisible(false);
|
||||
int idx = m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt();
|
||||
if (m_buttons.value(idx))
|
||||
m_buttons.value(idx)->setChecked(false);
|
||||
if (IEditor *editor = Core::EditorManager::instance()->currentEditor())
|
||||
editor->widget()->setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
int OutputPaneManager::findIndexForPage(IOutputPane *out)
|
||||
{
|
||||
if (!out)
|
||||
return -1;
|
||||
|
||||
int stackIndex = -1;
|
||||
QMap<int, IOutputPane*>::const_iterator it = m_pageMap.constBegin();
|
||||
while (it != m_pageMap.constEnd()) {
|
||||
if (it.value() == out) {
|
||||
stackIndex = it.key();
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
if (stackIndex > -1)
|
||||
return m_widgetComboBox->findData(stackIndex);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void OutputPaneManager::ensurePageVisible(int idx)
|
||||
{
|
||||
if (m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt() != idx) {
|
||||
m_widgetComboBox->setCurrentIndex(m_widgetComboBox->findData(idx));
|
||||
} else {
|
||||
changePage();
|
||||
}
|
||||
}
|
||||
|
||||
void OutputPaneManager::updateNavigateState()
|
||||
{
|
||||
IOutputPane* pane = qobject_cast<IOutputPane*>(sender());
|
||||
int idx = findIndexForPage(pane);
|
||||
if (m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt() == idx) {
|
||||
m_prevAction->setEnabled(pane->canNavigate() && pane->canPrevious());
|
||||
m_nextAction->setEnabled(pane->canNavigate() && pane->canNext());
|
||||
}
|
||||
}
|
||||
|
||||
// Slot connected to showPage signal of each page
|
||||
void OutputPaneManager::showPage(bool focus)
|
||||
{
|
||||
int idx = findIndexForPage(qobject_cast<IOutputPane*>(sender()));
|
||||
showPage(idx, focus);
|
||||
}
|
||||
|
||||
void OutputPaneManager::showPage(int idx, bool focus)
|
||||
{
|
||||
IOutputPane *out = m_pageMap.value(idx);
|
||||
if (idx > -1) {
|
||||
if (!OutputPanePlaceHolder::m_current) {
|
||||
// In this mode we don't have a placeholder
|
||||
// switch to the output mode and switch the page
|
||||
ICore::instance()->modeManager()->activateMode(Constants::MODE_OUTPUT);
|
||||
ensurePageVisible(idx);
|
||||
} else {
|
||||
// else we make that page visible
|
||||
OutputPanePlaceHolder::m_current->setVisible(true);
|
||||
ensurePageVisible(idx);
|
||||
if (focus && out->canFocus())
|
||||
out->setFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OutputPaneManager::togglePage(bool focus)
|
||||
{
|
||||
int idx = findIndexForPage(qobject_cast<IOutputPane*>(sender()));
|
||||
if (OutputPanePlaceHolder::m_current
|
||||
&& OutputPanePlaceHolder::m_current->isVisible()
|
||||
&& m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt() == idx) {
|
||||
slotHide();
|
||||
} else {
|
||||
showPage(idx, focus);
|
||||
}
|
||||
}
|
||||
|
||||
void OutputPaneManager::setCloseable(bool b)
|
||||
{
|
||||
m_closeButton->setVisible(b);
|
||||
}
|
||||
|
||||
bool OutputPaneManager::closeable()
|
||||
{
|
||||
return m_closeButton->isVisibleTo(m_closeButton->parentWidget());
|
||||
}
|
||||
|
||||
void OutputPaneManager::focusInEvent(QFocusEvent *e)
|
||||
{
|
||||
if (m_outputWidgetPane->currentWidget())
|
||||
m_outputWidgetPane->currentWidget()->setFocus(e->reason());
|
||||
}
|
||||
|
||||
void OutputPaneManager::changePage()
|
||||
{
|
||||
if (m_outputWidgetPane->count() <= 0)
|
||||
return;
|
||||
|
||||
if (!m_pageMap.contains(m_lastIndex)) {
|
||||
int idx = m_outputWidgetPane->currentIndex();
|
||||
m_pageMap.value(idx)->visibilityChanged(true);
|
||||
if (m_buttons.value(idx)) {
|
||||
if (OutputPanePlaceHolder::m_current)
|
||||
m_buttons.value(idx)->setChecked(OutputPanePlaceHolder::m_current->isVisible());
|
||||
else
|
||||
m_buttons.value(idx)->setChecked(false);
|
||||
}
|
||||
m_lastIndex = idx;
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt();
|
||||
if (m_lastIndex != idx) {
|
||||
m_outputWidgetPane->setCurrentIndex(idx);
|
||||
m_opToolBarWidgets->setCurrentIndex(idx);
|
||||
m_pageMap.value(idx)->visibilityChanged(true);
|
||||
m_pageMap.value(m_lastIndex)->visibilityChanged(false);
|
||||
|
||||
bool canNavigate = m_pageMap.value(idx)->canNavigate();
|
||||
m_prevAction->setEnabled(canNavigate && m_pageMap.value(idx)->canPrevious());
|
||||
m_nextAction->setEnabled(canNavigate && m_pageMap.value(idx)->canNext());
|
||||
}
|
||||
|
||||
if (m_buttons.value(m_lastIndex))
|
||||
m_buttons.value(m_lastIndex)->setChecked(false);
|
||||
|
||||
if (m_buttons.value(idx)) {
|
||||
if (OutputPanePlaceHolder::m_current)
|
||||
m_buttons.value(idx)->setChecked(OutputPanePlaceHolder::m_current->isVisible());
|
||||
else
|
||||
m_buttons.value(idx)->setChecked(false);
|
||||
}
|
||||
|
||||
m_lastIndex = idx;
|
||||
}
|
||||
|
||||
void OutputPaneManager::clearPage()
|
||||
{
|
||||
if (m_pageMap.contains(m_outputWidgetPane->currentIndex()))
|
||||
m_pageMap.value(m_outputWidgetPane->currentIndex())->clearContents();
|
||||
}
|
||||
|
||||
|
||||
OutputPaneToggleButton::OutputPaneToggleButton(int number, const QString &text, QWidget *parent)
|
||||
: QPushButton(parent)
|
||||
, m_number(QString::number(number))
|
||||
, m_text(text)
|
||||
{
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
setCheckable(true);
|
||||
setStyleSheet(
|
||||
"QPushButton { border-image: url(:/core/images/panel_button.png) 2 2 2 19;"
|
||||
" border-width: 2px 2px 2px 19px; padding-left: -17; padding-right: 4 } "
|
||||
"QPushButton:checked { border-image: url(:/core/images/panel_button_checked.png) 2 2 2 19 } "
|
||||
#ifndef Q_WS_MAC // Mac UIs usually don't hover
|
||||
"QPushButton:checked:hover { border-image: url(:/core/images/panel_button_checked_hover.png) 2 2 2 19 } "
|
||||
"QPushButton:pressed:hover { border-image: url(:/core/images/panel_button_pressed.png) 2 2 2 19 } "
|
||||
"QPushButton:hover { border-image: url(:/core/images/panel_button_hover.png) 2 2 2 19 } "
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
QSize OutputPaneToggleButton::sizeHint() const
|
||||
{
|
||||
ensurePolished();
|
||||
|
||||
QSize s = fontMetrics().size(Qt::TextSingleLine, m_text);
|
||||
|
||||
// Expand to account for border image set by stylesheet above
|
||||
s.rwidth() += 19 + 5 + 2;
|
||||
s.rheight() += 2 + 2;
|
||||
|
||||
return s.expandedTo(QApplication::globalStrut());
|
||||
}
|
||||
|
||||
void OutputPaneToggleButton::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
// For drawing the style sheet stuff
|
||||
QPushButton::paintEvent(event);
|
||||
|
||||
const QFontMetrics fm = fontMetrics();
|
||||
const int baseLine = (height() - fm.height() + 1) / 2 + fm.ascent();
|
||||
const int numberWidth = fm.width(m_number);
|
||||
|
||||
QPainter p(this);
|
||||
p.setFont(font());
|
||||
p.setPen(Qt::white);
|
||||
p.drawText((20 - numberWidth) / 2, baseLine, m_number);
|
||||
if (!isChecked())
|
||||
p.setPen(Qt::black);
|
||||
int leftPart = 22;
|
||||
p.drawText(leftPart, baseLine, fm.elidedText(m_text, Qt::ElideRight, width() - leftPart - 1));
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef OUTPUTPANE_H
|
||||
#define OUTPUTPANE_H
|
||||
|
||||
#include "core_global.h"
|
||||
|
||||
#include <QtCore/QMap>
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QComboBox;
|
||||
class QToolButton;
|
||||
class QStackedWidget;
|
||||
class QPushButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
|
||||
class IMode;
|
||||
class IOutputPane;
|
||||
|
||||
namespace Internal {
|
||||
class OutputPaneManager;
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
|
||||
class CORE_EXPORT OutputPanePlaceHolder : public QWidget
|
||||
{
|
||||
friend class Core::Internal::OutputPaneManager; // needs to set m_visible and thus access m_current
|
||||
Q_OBJECT
|
||||
public:
|
||||
OutputPanePlaceHolder(Core::IMode *mode, QWidget *parent = 0);
|
||||
~OutputPanePlaceHolder();
|
||||
void setCloseable(bool b);
|
||||
bool closeable();
|
||||
static OutputPanePlaceHolder *getCurrent() { return m_current; }
|
||||
|
||||
private slots:
|
||||
void currentModeChanged(Core::IMode *);
|
||||
private:
|
||||
Core::IMode *m_mode;
|
||||
bool m_closeable;
|
||||
static OutputPanePlaceHolder* m_current;
|
||||
};
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class OutputPaneManager : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void init();
|
||||
static OutputPaneManager *instance();
|
||||
void setCloseable(bool b);
|
||||
bool closeable();
|
||||
QWidget *buttonsWidget();
|
||||
void updateStatusButtons(bool visible);
|
||||
|
||||
public slots:
|
||||
void slotHide();
|
||||
void slotNext();
|
||||
void slotPrev();
|
||||
void shortcutTriggered();
|
||||
|
||||
protected:
|
||||
void focusInEvent(QFocusEvent *e);
|
||||
|
||||
private slots:
|
||||
void changePage();
|
||||
void showPage(bool focus);
|
||||
void togglePage(bool focus);
|
||||
void clearPage();
|
||||
void updateToolTip();
|
||||
void buttonTriggered();
|
||||
void updateNavigateState();
|
||||
|
||||
private:
|
||||
// the only class that is allowed to create and destroy
|
||||
friend class MainWindow;
|
||||
|
||||
static void create();
|
||||
static void destroy();
|
||||
|
||||
OutputPaneManager(QWidget *parent = 0);
|
||||
~OutputPaneManager();
|
||||
|
||||
void showPage(int idx, bool focus);
|
||||
void ensurePageVisible(int idx);
|
||||
int findIndexForPage(IOutputPane *out);
|
||||
QComboBox *m_widgetComboBox;
|
||||
QToolButton *m_clearButton;
|
||||
QToolButton *m_closeButton;
|
||||
|
||||
QAction *m_nextAction;
|
||||
QAction *m_prevAction;
|
||||
QToolButton *m_prevToolButton;
|
||||
QToolButton *m_nextToolButton;
|
||||
QWidget *m_toolBar;
|
||||
|
||||
QMap<int, Core::IOutputPane*> m_pageMap;
|
||||
int m_lastIndex;
|
||||
|
||||
QStackedWidget *m_outputWidgetPane;
|
||||
QStackedWidget *m_opToolBarWidgets;
|
||||
QWidget *m_buttonsWidget;
|
||||
QMap<int, QPushButton *> m_buttons;
|
||||
QMap<QAction *, int> m_actions;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
#endif // OUTPUTPANE_H
|
@ -1,167 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "futureprogress.h"
|
||||
#include "progresspie.h"
|
||||
|
||||
#include <QtGui/QColor>
|
||||
#include <QtGui/QVBoxLayout>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QProgressBar>
|
||||
#include <QtGui/QHBoxLayout>
|
||||
|
||||
|
||||
using namespace Core;
|
||||
|
||||
FutureProgress::FutureProgress(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_progress(new ProgressBar),
|
||||
m_widget(0),
|
||||
m_widgetLayout(new QHBoxLayout)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
setLayout(layout);
|
||||
layout->addWidget(m_progress);
|
||||
layout->setMargin(0);
|
||||
layout->setSpacing(0);
|
||||
layout->addLayout(m_widgetLayout);
|
||||
m_widgetLayout->setContentsMargins(7, 0, 7, 0);
|
||||
m_widgetLayout->setSpacing(0);
|
||||
|
||||
connect(&m_watcher, SIGNAL(started()), this, SLOT(setStarted()));
|
||||
connect(&m_watcher, SIGNAL(finished()), this, SLOT(setFinished()));
|
||||
connect(&m_watcher, SIGNAL(progressRangeChanged(int,int)), this, SLOT(setProgressRange(int,int)));
|
||||
connect(&m_watcher, SIGNAL(progressValueChanged(int)), this, SLOT(setProgressValue(int)));
|
||||
connect(&m_watcher, SIGNAL(progressTextChanged(const QString&)),
|
||||
this, SLOT(setProgressText(const QString&)));
|
||||
connect(m_progress, SIGNAL(clicked()), this, SLOT(cancel()));
|
||||
}
|
||||
|
||||
FutureProgress::~FutureProgress()
|
||||
{
|
||||
if (m_widget)
|
||||
delete m_widget;
|
||||
}
|
||||
|
||||
void FutureProgress::setWidget(QWidget *widget)
|
||||
{
|
||||
if (m_widget)
|
||||
delete m_widget;
|
||||
QSizePolicy sp = widget->sizePolicy();
|
||||
sp.setHorizontalPolicy(QSizePolicy::Ignored);
|
||||
widget->setSizePolicy(sp);
|
||||
m_widget = widget;
|
||||
if (m_widget)
|
||||
m_widgetLayout->addWidget(m_widget);
|
||||
}
|
||||
|
||||
void FutureProgress::setTitle(const QString &title)
|
||||
{
|
||||
m_progress->setTitle(title);
|
||||
}
|
||||
|
||||
QString FutureProgress::title() const
|
||||
{
|
||||
return m_progress->title();
|
||||
}
|
||||
|
||||
void FutureProgress::cancel()
|
||||
{
|
||||
m_watcher.future().cancel();
|
||||
}
|
||||
|
||||
void FutureProgress::setStarted()
|
||||
{
|
||||
m_progress->reset();
|
||||
m_progress->setError(false);
|
||||
m_progress->setRange(m_watcher.progressMinimum(), m_watcher.progressMaximum());
|
||||
m_progress->setValue(m_watcher.progressValue());
|
||||
// if (m_watcher.progressMinimum() == 0 && m_watcher.progressMaximum() == 0)
|
||||
// m_progress->startAnimation();
|
||||
}
|
||||
|
||||
void FutureProgress::setFinished()
|
||||
{
|
||||
// m_progress->stopAnimation();
|
||||
setToolTip(m_watcher.future().progressText());
|
||||
if (m_watcher.future().isCanceled()) {
|
||||
m_progress->setError(true);
|
||||
// m_progress->execGlowOut(true);
|
||||
} else {
|
||||
m_progress->setError(false);
|
||||
// m_progress->execGlowOut(false);
|
||||
}
|
||||
// m_progress->showToolTip();
|
||||
emit finished();
|
||||
}
|
||||
|
||||
void FutureProgress::setProgressRange(int min, int max)
|
||||
{
|
||||
m_progress->setRange(min, max);
|
||||
if (min != 0 || max != 0) {
|
||||
// m_progress->setUsingAnimation(false);
|
||||
} else {
|
||||
// m_progress->setUsingAnimation(true);
|
||||
if (m_watcher.future().isRunning()) {
|
||||
//m_progress->startAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FutureProgress::setProgressValue(int val)
|
||||
{
|
||||
m_progress->setValue(val);
|
||||
}
|
||||
|
||||
void FutureProgress::setProgressText(const QString &text)
|
||||
{
|
||||
setToolTip(text);
|
||||
}
|
||||
|
||||
void FutureProgress::setFuture(const QFuture<void> &future)
|
||||
{
|
||||
m_watcher.setFuture(future);
|
||||
}
|
||||
|
||||
QFuture<void> FutureProgress::future() const
|
||||
{
|
||||
return m_watcher.future();
|
||||
}
|
||||
|
||||
void FutureProgress::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
emit clicked();
|
||||
QWidget::mousePressEvent(event);
|
||||
}
|
||||
|
||||
bool FutureProgress::hasError() const
|
||||
{
|
||||
return m_progress->hasError();
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef FUTUREPROGRESS_H
|
||||
#define FUTUREPROGRESS_H
|
||||
|
||||
#include <coreplugin/core_global.h>
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QFuture>
|
||||
#include <QtCore/QFutureWatcher>
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QProgressBar;
|
||||
class QHBoxLayout;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class ProgressBar;
|
||||
|
||||
namespace Core {
|
||||
|
||||
class CORE_EXPORT FutureProgress : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FutureProgress(QWidget *parent = 0);
|
||||
~FutureProgress();
|
||||
|
||||
void setFuture(const QFuture<void> &future);
|
||||
QFuture<void> future() const;
|
||||
|
||||
void setTitle(const QString &title);
|
||||
QString title() const;
|
||||
|
||||
bool hasError() const;
|
||||
|
||||
void setWidget(QWidget *widget);
|
||||
QWidget *widget() const { return m_widget; }
|
||||
|
||||
signals:
|
||||
void clicked();
|
||||
void finished();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
|
||||
private slots:
|
||||
void cancel();
|
||||
void setStarted();
|
||||
void setFinished();
|
||||
void setProgressRange(int min, int max);
|
||||
void setProgressValue(int val);
|
||||
void setProgressText(const QString &text);
|
||||
|
||||
private:
|
||||
QFutureWatcher<void> m_watcher;
|
||||
ProgressBar *m_progress;
|
||||
QWidget *m_widget;
|
||||
QHBoxLayout *m_widgetLayout;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif // FUTUREPROGRESS_H
|
@ -1,117 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "progressmanager_p.h"
|
||||
#include "progressview.h"
|
||||
#include "baseview.h"
|
||||
#include "coreconstants.h"
|
||||
#include "icore.h"
|
||||
#include "uniqueidmanager.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
using namespace Core;
|
||||
using namespace Core::Internal;
|
||||
|
||||
ProgressManagerPrivate::ProgressManagerPrivate(QObject *parent)
|
||||
: ProgressManager(parent)
|
||||
{
|
||||
m_progressView = new ProgressView;
|
||||
ICore *core = ICore::instance();
|
||||
connect(core, SIGNAL(coreAboutToClose()), this, SLOT(cancelAllRunningTasks()));
|
||||
}
|
||||
|
||||
ProgressManagerPrivate::~ProgressManagerPrivate()
|
||||
{
|
||||
}
|
||||
|
||||
void ProgressManagerPrivate::init()
|
||||
{
|
||||
}
|
||||
|
||||
void ProgressManagerPrivate::cancelTasks(const QString &type)
|
||||
{
|
||||
bool found = false;
|
||||
QMap<QFutureWatcher<void> *, QString>::iterator task = m_runningTasks.begin();
|
||||
while (task != m_runningTasks.end()) {
|
||||
if (task.value() != type) {
|
||||
++task;
|
||||
continue;
|
||||
}
|
||||
found = true;
|
||||
disconnect(task.key(), SIGNAL(finished()), this, SLOT(taskFinished()));
|
||||
task.key()->cancel();
|
||||
delete task.key();
|
||||
task = m_runningTasks.erase(task);
|
||||
}
|
||||
if (found) {
|
||||
emit allTasksFinished(type);
|
||||
}
|
||||
}
|
||||
|
||||
void ProgressManagerPrivate::cancelAllRunningTasks()
|
||||
{
|
||||
QMap<QFutureWatcher<void> *, QString>::const_iterator task = m_runningTasks.constBegin();
|
||||
while (task != m_runningTasks.constEnd()) {
|
||||
disconnect(task.key(), SIGNAL(finished()), this, SLOT(taskFinished()));
|
||||
task.key()->cancel();
|
||||
delete task.key();
|
||||
++task;
|
||||
}
|
||||
m_runningTasks.clear();
|
||||
}
|
||||
|
||||
FutureProgress *ProgressManagerPrivate::addTask(const QFuture<void> &future, const QString &title, const QString &type, PersistentType persistency)
|
||||
{
|
||||
QFutureWatcher<void> *watcher = new QFutureWatcher<void>();
|
||||
m_runningTasks.insert(watcher, type);
|
||||
connect(watcher, SIGNAL(finished()), this, SLOT(taskFinished()));
|
||||
watcher->setFuture(future);
|
||||
emit taskStarted(type);
|
||||
return m_progressView->addTask(future, title, type, persistency);
|
||||
}
|
||||
|
||||
QWidget *ProgressManagerPrivate::progressView()
|
||||
{
|
||||
return m_progressView;
|
||||
}
|
||||
|
||||
void ProgressManagerPrivate::taskFinished()
|
||||
{
|
||||
QObject *taskObject = sender();
|
||||
QTC_ASSERT(taskObject, return);
|
||||
QFutureWatcher<void> *task = static_cast<QFutureWatcher<void> *>(taskObject);
|
||||
QString type = m_runningTasks.value(task);
|
||||
m_runningTasks.remove(task);
|
||||
delete task;
|
||||
|
||||
if (!m_runningTasks.values().contains(type)) {
|
||||
emit allTasksFinished(type);
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef PROGRESSMANAGER_H
|
||||
#define PROGRESSMANAGER_H
|
||||
|
||||
#include <coreplugin/core_global.h>
|
||||
#include <coreplugin/progressmanager/futureprogress.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QFuture>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class CORE_EXPORT ProgressManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum PersistentType { CloseOnSuccess, KeepOnFinish };
|
||||
|
||||
ProgressManager(QObject *parent = 0) : QObject(parent) {}
|
||||
virtual ~ProgressManager() {}
|
||||
|
||||
virtual FutureProgress *addTask(const QFuture<void> &future, const QString &title, const QString &type, PersistentType persistency = KeepOnFinish) = 0;
|
||||
|
||||
public slots:
|
||||
virtual void cancelTasks(const QString &type) = 0;
|
||||
|
||||
signals:
|
||||
void taskStarted(const QString &type);
|
||||
void allTasksFinished(const QString &type);
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif //PROGRESSMANAGER_H
|
@ -1,70 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef PROGRESSMANAGER_P_H
|
||||
#define PROGRESSMANAGER_P_H
|
||||
|
||||
#include "progressmanager.h"
|
||||
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QFutureWatcher>
|
||||
|
||||
namespace Core {
|
||||
namespace Internal {
|
||||
|
||||
class ProgressView;
|
||||
|
||||
class ProgressManagerPrivate : public Core::ProgressManager
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProgressManagerPrivate(QObject *parent = 0);
|
||||
~ProgressManagerPrivate();
|
||||
void init();
|
||||
|
||||
FutureProgress *addTask(const QFuture<void> &future, const QString &title, const QString &type, PersistentType persistency);
|
||||
|
||||
QWidget *progressView();
|
||||
|
||||
public slots:
|
||||
void cancelTasks(const QString &type);
|
||||
|
||||
private slots:
|
||||
void taskFinished();
|
||||
void cancelAllRunningTasks();
|
||||
private:
|
||||
QPointer<ProgressView> m_progressView;
|
||||
QMap<QFutureWatcher<void> *, QString> m_runningTasks;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
#endif // PROGRESSMANAGER_P_H
|
@ -1,217 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "progresspie.h"
|
||||
|
||||
#include <utils/stylehelper.h>
|
||||
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QFont>
|
||||
#include <QtGui/QBrush>
|
||||
#include <QtGui/QColor>
|
||||
#include <QtDebug>
|
||||
#define PROGRESSBAR_HEIGHT 11
|
||||
|
||||
ProgressBar::ProgressBar(QWidget *parent)
|
||||
: QWidget(parent), m_error(false), m_minimum(1), m_maximum(100), m_value(1)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
ProgressBar::~ProgressBar()
|
||||
{
|
||||
}
|
||||
|
||||
void ProgressBar::reset()
|
||||
{
|
||||
m_value = m_minimum;
|
||||
update();
|
||||
}
|
||||
|
||||
void ProgressBar::setRange(int minimum, int maximum)
|
||||
{
|
||||
m_minimum = minimum;
|
||||
m_maximum = maximum;
|
||||
if (m_value < m_minimum || m_value > m_maximum)
|
||||
m_value = m_minimum;
|
||||
update();
|
||||
}
|
||||
|
||||
void ProgressBar::setValue(int value)
|
||||
{
|
||||
if (m_value == value
|
||||
|| m_value < m_minimum
|
||||
|| m_value > m_maximum) {
|
||||
return;
|
||||
}
|
||||
m_value = value;
|
||||
update();
|
||||
}
|
||||
|
||||
QString ProgressBar::title() const
|
||||
{
|
||||
return m_title;
|
||||
}
|
||||
|
||||
bool ProgressBar::hasError() const
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
|
||||
void ProgressBar::setTitle(const QString &title)
|
||||
{
|
||||
m_title = title;
|
||||
update();
|
||||
}
|
||||
|
||||
void ProgressBar::setError(bool on)
|
||||
{
|
||||
m_error = on;
|
||||
update();
|
||||
}
|
||||
|
||||
QSize ProgressBar::sizeHint() const
|
||||
{
|
||||
QSize s;
|
||||
s.setWidth(50);
|
||||
s.setHeight(fontMetrics().height() + PROGRESSBAR_HEIGHT + 7);
|
||||
return s;
|
||||
}
|
||||
|
||||
namespace { const int INDENT = 7; }
|
||||
|
||||
void ProgressBar::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->modifiers() == Qt::NoModifier
|
||||
&& event->x() >= size().width()-INDENT-m_progressHeight) {
|
||||
event->accept();
|
||||
emit clicked();
|
||||
return;
|
||||
}
|
||||
QWidget::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void ProgressBar::mouseMoveEvent(QMouseEvent *)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void ProgressBar::paintEvent(QPaintEvent *)
|
||||
{
|
||||
// TODO move font into Utils::StyleHelper
|
||||
// TODO use Utils::StyleHelper white
|
||||
|
||||
double range = maximum() - minimum();
|
||||
double percent = 0.50;
|
||||
if (range != 0)
|
||||
percent = (value() - minimum()) / range;
|
||||
if (percent > 1)
|
||||
percent = 1;
|
||||
else if (percent < 0)
|
||||
percent = 0;
|
||||
|
||||
QPainter p(this);
|
||||
QFont boldFont(p.font());
|
||||
boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize());
|
||||
boldFont.setBold(true);
|
||||
p.setFont(boldFont);
|
||||
QFontMetrics fm(boldFont);
|
||||
|
||||
// Draw separator
|
||||
int h = fm.height();
|
||||
p.setPen(QColor(0, 0, 0, 70));
|
||||
p.drawLine(0,0, size().width(), 0);
|
||||
|
||||
p.setPen(QColor(255, 255, 255, 70));
|
||||
p.drawLine(0, 1, size().width(), 1);
|
||||
|
||||
QRect textRect = rect().adjusted(0, 0, -1, 0);
|
||||
textRect.setHeight(h+5);
|
||||
|
||||
p.setPen(QColor(30, 30, 30, 80));
|
||||
p.drawText(textRect, Qt::AlignHCenter | Qt::AlignBottom, m_title);
|
||||
p.translate(0, -1);
|
||||
p.setPen(Utils::StyleHelper::panelTextColor());
|
||||
p.drawText(textRect, Qt::AlignHCenter | Qt::AlignBottom, m_title);
|
||||
p.translate(0, 1);
|
||||
|
||||
m_progressHeight = PROGRESSBAR_HEIGHT;
|
||||
m_progressHeight += ((m_progressHeight % 2) + 1) % 2; // make odd
|
||||
// draw outer rect
|
||||
QRect rect(INDENT - 1, h+6, size().width()-2*INDENT, m_progressHeight-1);
|
||||
p.setPen(Utils::StyleHelper::panelTextColor());
|
||||
p.drawRect(rect);
|
||||
|
||||
// draw inner rect
|
||||
QColor c = Utils::StyleHelper::panelTextColor();
|
||||
c.setAlpha(180);
|
||||
p.setPen(Qt::NoPen);
|
||||
|
||||
QRect inner = rect.adjusted(2, 2, -1, -1);
|
||||
inner.adjust(0, 0, qRound((percent - 1) * inner.width()), 0);
|
||||
if (m_error) {
|
||||
QColor red(255, 60, 0, 210);
|
||||
c = red;
|
||||
// avoid too small red bar
|
||||
if (inner.width() < 10)
|
||||
inner.adjust(0, 0, 10 - inner.width(), 0);
|
||||
} else if (value() == maximum()) {
|
||||
c = QColor(120, 245, 90, 180);
|
||||
}
|
||||
|
||||
QLinearGradient grad(inner.topLeft(), inner.bottomLeft());
|
||||
grad.setColorAt(0, c.lighter(114));
|
||||
grad.setColorAt(0.5, c.lighter(104));
|
||||
grad.setColorAt(0.51, c.darker(108));
|
||||
grad.setColorAt(1, c.darker(120));
|
||||
|
||||
p.setBrush(grad);
|
||||
p.drawRect(inner);
|
||||
|
||||
if (value() < maximum() && !m_error) {
|
||||
QColor cancelOutline = Utils::StyleHelper::panelTextColor();
|
||||
p.setPen(cancelOutline);
|
||||
QRect cancelRect(rect.right() - m_progressHeight + 2, rect.top(), m_progressHeight-1, rect.height());
|
||||
if (cancelRect.contains(mapFromGlobal(QCursor::pos())))
|
||||
p.setBrush(QColor(230, 90, 40, 190));
|
||||
else
|
||||
p.setBrush(Qt::NoBrush);
|
||||
|
||||
p.drawRect(cancelRect);
|
||||
|
||||
p.setPen(QPen(QColor(0, 0, 0, 70), 3));
|
||||
p.drawLine(cancelRect.center()+QPoint(-1,-1), cancelRect.center()+QPoint(+3,+3));
|
||||
p.drawLine(cancelRect.center()+QPoint(+3,-1), cancelRect.center()+QPoint(-1,+3));
|
||||
|
||||
p.setPen(Utils::StyleHelper::panelTextColor());
|
||||
p.drawLine(cancelRect.center()+QPoint(-1,-1), cancelRect.center()+QPoint(+3,+3));
|
||||
p.drawLine(cancelRect.center()+QPoint(+3,-1), cancelRect.center()+QPoint(-1,+3));
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef PROGRESSPIE_H
|
||||
#define PROGRESSPIE_H
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QProgressBar>
|
||||
#include <QtGui/QMouseEvent>
|
||||
|
||||
class ProgressBar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProgressBar(QWidget *parent = 0);
|
||||
~ProgressBar();
|
||||
|
||||
QString title() const;
|
||||
void setTitle(const QString &title);
|
||||
// TODO rename setError
|
||||
void setError(bool on);
|
||||
bool hasError() const;
|
||||
QSize sizeHint() const;
|
||||
void paintEvent(QPaintEvent *);
|
||||
void mouseMoveEvent(QMouseEvent *);
|
||||
|
||||
int minimum() const { return m_minimum; }
|
||||
int maximum() const { return m_maximum; }
|
||||
int value() const { return m_value; }
|
||||
void reset();
|
||||
void setRange(int minimum, int maximum);
|
||||
void setValue(int value);
|
||||
signals:
|
||||
void clicked();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
|
||||
private:
|
||||
QString m_text;
|
||||
QString m_title;
|
||||
bool m_error;
|
||||
int m_progressHeight;
|
||||
|
||||
int m_minimum;
|
||||
int m_maximum;
|
||||
int m_value;
|
||||
};
|
||||
|
||||
#endif // PROGRESSPIE_H
|
@ -1,142 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "progressview.h"
|
||||
#include "futureprogress.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QtGui/QHBoxLayout>
|
||||
|
||||
using namespace Core;
|
||||
using namespace Core::Internal;
|
||||
|
||||
ProgressView::ProgressView(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_layout = new QVBoxLayout;
|
||||
setLayout(m_layout);
|
||||
m_layout->setMargin(0);
|
||||
m_layout->setSpacing(0);
|
||||
setWindowTitle(tr("Processes"));
|
||||
}
|
||||
|
||||
ProgressView::~ProgressView()
|
||||
{
|
||||
qDeleteAll(m_taskList);
|
||||
m_taskList.clear();
|
||||
m_type.clear();
|
||||
m_keep.clear();
|
||||
}
|
||||
|
||||
FutureProgress *ProgressView::addTask(const QFuture<void> &future,
|
||||
const QString &title,
|
||||
const QString &type,
|
||||
ProgressManager::PersistentType persistency)
|
||||
{
|
||||
removeOldTasks(type);
|
||||
if (m_taskList.size() == 3)
|
||||
removeOneOldTask();
|
||||
FutureProgress *progress = new FutureProgress(this);
|
||||
progress->setTitle(title);
|
||||
progress->setFuture(future);
|
||||
m_layout->insertWidget(0, progress);
|
||||
m_taskList.append(progress);
|
||||
m_type.insert(progress, type);
|
||||
m_keep.insert(progress, (persistency == ProgressManager::KeepOnFinish));
|
||||
connect(progress, SIGNAL(finished()), this, SLOT(slotFinished()));
|
||||
return progress;
|
||||
}
|
||||
|
||||
void ProgressView::removeOldTasks(const QString &type, bool keepOne)
|
||||
{
|
||||
bool firstFound = !keepOne; // start with false if we want to keep one
|
||||
QList<FutureProgress *>::iterator i = m_taskList.end();
|
||||
while (i != m_taskList.begin()) {
|
||||
--i;
|
||||
if (m_type.value(*i) == type) {
|
||||
if (firstFound && (*i)->future().isFinished()) {
|
||||
deleteTask(*i);
|
||||
i = m_taskList.erase(i);
|
||||
}
|
||||
firstFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProgressView::deleteTask(FutureProgress *progress)
|
||||
{
|
||||
m_type.remove(progress);
|
||||
m_keep.remove(progress);
|
||||
layout()->removeWidget(progress);
|
||||
progress->hide();
|
||||
progress->deleteLater();
|
||||
}
|
||||
|
||||
void ProgressView::removeOneOldTask()
|
||||
{
|
||||
if (m_taskList.isEmpty())
|
||||
return;
|
||||
// look for oldest ended process
|
||||
for (QList<FutureProgress *>::iterator i = m_taskList.begin(); i != m_taskList.end(); ++i) {
|
||||
if ((*i)->future().isFinished()) {
|
||||
deleteTask(*i);
|
||||
i = m_taskList.erase(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// no ended process, look for a task type with multiple running tasks and remove the oldest one
|
||||
for (QList<FutureProgress *>::iterator i = m_taskList.begin(); i != m_taskList.end(); ++i) {
|
||||
QString type = m_type.value(*i);
|
||||
if (m_type.keys(type).size() > 1) { // don't care for optimizations it's only a handful of entries
|
||||
deleteTask(*i);
|
||||
i = m_taskList.erase(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// no ended process, no type with multiple processes, just remove the oldest task
|
||||
FutureProgress *task = m_taskList.takeFirst();
|
||||
deleteTask(task);
|
||||
}
|
||||
|
||||
void ProgressView::removeTask(FutureProgress *task)
|
||||
{
|
||||
m_taskList.removeAll(task);
|
||||
deleteTask(task);
|
||||
}
|
||||
|
||||
void ProgressView::slotFinished()
|
||||
{
|
||||
FutureProgress *progress = qobject_cast<FutureProgress *>(sender());
|
||||
QTC_ASSERT(progress, return);
|
||||
if (m_keep.contains(progress) && !m_keep.value(progress) && !progress->hasError())
|
||||
removeTask(progress);
|
||||
removeOldTasks(m_type.value(progress), true);
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef PROGRESSVIEW_H
|
||||
#define PROGRESSVIEW_H
|
||||
|
||||
#include "progressmanager.h"
|
||||
|
||||
#include <QtCore/QFuture>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtGui/QVBoxLayout>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class FutureProgress;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class ProgressView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ProgressView(QWidget *parent = 0);
|
||||
~ProgressView();
|
||||
|
||||
/** The returned FutureProgress instance is guaranteed to live till next main loop event processing (deleteLater). */
|
||||
FutureProgress *addTask(const QFuture<void> &future,
|
||||
const QString &title,
|
||||
const QString &type,
|
||||
ProgressManager::PersistentType persistency);
|
||||
|
||||
private slots:
|
||||
void slotFinished();
|
||||
|
||||
private:
|
||||
void removeOldTasks(const QString &type, bool keepOne = false);
|
||||
void removeOneOldTask();
|
||||
void removeTask(FutureProgress *task);
|
||||
void deleteTask(FutureProgress *task);
|
||||
|
||||
QVBoxLayout *m_layout;
|
||||
QList<FutureProgress *> m_taskList;
|
||||
QHash<FutureProgress *, QString> m_type;
|
||||
QHash<FutureProgress *, bool> m_keep;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
#endif // PROGRESSVIEW_H
|
@ -1,64 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef METATYPEDECLARATIONS_H
|
||||
#define METATYPEDECLARATIONS_H
|
||||
|
||||
#include <coreplugin/messagemanager.h>
|
||||
#include <coreplugin/filemanager.h>
|
||||
#include <coreplugin/ifile.h>
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMetaType>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QMainWindow;
|
||||
class QStatusBar;
|
||||
class QSettings;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
Q_DECLARE_METATYPE(Core::MessageManager*)
|
||||
Q_DECLARE_METATYPE(Core::FileManager*)
|
||||
Q_DECLARE_METATYPE(Core::IFile*)
|
||||
Q_DECLARE_METATYPE(QList<Core::IFile*>)
|
||||
Q_DECLARE_METATYPE(Core::IEditor*)
|
||||
Q_DECLARE_METATYPE(QList<Core::IEditor*>)
|
||||
Q_DECLARE_METATYPE(Core::EditorGroup*)
|
||||
Q_DECLARE_METATYPE(QList<Core::EditorGroup*>)
|
||||
Q_DECLARE_METATYPE(Core::EditorManager*)
|
||||
Q_DECLARE_METATYPE(Core::ICore*)
|
||||
|
||||
Q_DECLARE_METATYPE(QMainWindow*)
|
||||
Q_DECLARE_METATYPE(QStatusBar*)
|
||||
Q_DECLARE_METATYPE(QSettings*)
|
||||
|
||||
#endif // METATYPEDECLARATIONS_H
|
@ -1,365 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "qworkbench_wrapper.h"
|
||||
|
||||
#include <wrap_helpers.h>
|
||||
|
||||
#include <coreplugin/messagemanager.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QSettings>
|
||||
|
||||
#include <QtGui/QMainWindow>
|
||||
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
namespace {
|
||||
enum { debugQWorkbenchWrappers = 0 };
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
namespace Internal {
|
||||
|
||||
// -- CorePrototype
|
||||
CorePrototype::CorePrototype(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
Core::MessageManager *CorePrototype::messageManager() const
|
||||
{
|
||||
return callee()->messageManager();
|
||||
}
|
||||
|
||||
Core::FileManager *CorePrototype::fileManager() const
|
||||
{
|
||||
return callee()->fileManager();
|
||||
}
|
||||
|
||||
Core::EditorManager *CorePrototype::editorManager() const
|
||||
{
|
||||
return callee()->editorManager();
|
||||
}
|
||||
|
||||
QMainWindow *CorePrototype::mainWindow() const
|
||||
{
|
||||
return callee()->mainWindow();
|
||||
}
|
||||
|
||||
QSettings *CorePrototype::settings() const
|
||||
{
|
||||
return callee()->settings();
|
||||
}
|
||||
|
||||
void CorePrototype::addAdditionalContext(int context)
|
||||
{
|
||||
callee()->addAdditionalContext(context);
|
||||
}
|
||||
|
||||
void CorePrototype::removeAdditionalContext(int context)
|
||||
{
|
||||
callee()->removeAdditionalContext(context);
|
||||
}
|
||||
|
||||
QString CorePrototype::toString() const
|
||||
{
|
||||
return QLatin1String("Core");
|
||||
}
|
||||
|
||||
CorePrototype::ICore *CorePrototype::callee() const
|
||||
{
|
||||
ICore *rc = qscriptvalue_cast<ICore *>(thisObject());
|
||||
QTC_ASSERT(rc, return 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// -- MessageManager
|
||||
|
||||
MessageManagerPrototype::MessageManagerPrototype(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void MessageManagerPrototype::displayStatusBarMessage(const QString &text, int ms)
|
||||
{
|
||||
MessageManager *mm = qscriptvalue_cast<MessageManager *>(thisObject());
|
||||
QTC_ASSERT(mm, return);
|
||||
mm->displayStatusBarMessage(text, ms);
|
||||
}
|
||||
|
||||
void MessageManagerPrototype::printToOutputPane(const QString &text, bool bringToForeground)
|
||||
{
|
||||
MessageManager *mm = qscriptvalue_cast<MessageManager *>(thisObject());
|
||||
QTC_ASSERT(mm, return);
|
||||
mm->printToOutputPane(text, bringToForeground);
|
||||
}
|
||||
|
||||
QString MessageManagerPrototype::toString() const
|
||||
{
|
||||
return QLatin1String("MessageManager");
|
||||
}
|
||||
|
||||
// -- FileManagerPrototype
|
||||
|
||||
FileManagerPrototype::FileManagerPrototype(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
FileManager *FileManagerPrototype::callee() const
|
||||
{
|
||||
FileManager *rc = qscriptvalue_cast<FileManager *>(thisObject());
|
||||
QTC_ASSERT(rc, return 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool FileManagerPrototype::addFiles(const QList<Core::IFile *> &files)
|
||||
{
|
||||
return callee()->addFiles(files);
|
||||
}
|
||||
|
||||
bool FileManagerPrototype::addFile(Core::IFile *file)
|
||||
{
|
||||
return callee()->addFile(file);
|
||||
}
|
||||
|
||||
bool FileManagerPrototype::removeFile(Core::IFile *file)
|
||||
{
|
||||
return callee()->removeFile(file);
|
||||
}
|
||||
|
||||
QList<Core::IFile*>
|
||||
FileManagerPrototype::saveModifiedFilesSilently(const QList<Core::IFile*> &files)
|
||||
{
|
||||
return callee()->saveModifiedFilesSilently(files);
|
||||
}
|
||||
|
||||
QString FileManagerPrototype::getSaveAsFileName(Core::IFile *file)
|
||||
{
|
||||
return callee()->getSaveAsFileName(file);
|
||||
}
|
||||
|
||||
bool FileManagerPrototype::isFileManaged(const QString &fileName) const
|
||||
{
|
||||
return callee()->isFileManaged(fileName);
|
||||
}
|
||||
|
||||
QList<Core::IFile *>
|
||||
FileManagerPrototype::managedFiles(const QString &fileName) const
|
||||
{
|
||||
return callee()->managedFiles(fileName);
|
||||
}
|
||||
|
||||
void FileManagerPrototype::blockFileChange(Core::IFile *file)
|
||||
{
|
||||
callee()->blockFileChange(file);
|
||||
}
|
||||
|
||||
void FileManagerPrototype::unblockFileChange(Core::IFile *file)
|
||||
{
|
||||
return callee()->unblockFileChange(file);
|
||||
}
|
||||
|
||||
void FileManagerPrototype::addToRecentFiles(const QString &fileName)
|
||||
{
|
||||
return callee()->addToRecentFiles(fileName);
|
||||
}
|
||||
|
||||
QStringList FileManagerPrototype::recentFiles() const
|
||||
{
|
||||
return callee()->recentFiles();
|
||||
}
|
||||
|
||||
QString FileManagerPrototype::toString() const
|
||||
{
|
||||
return QLatin1String("FileManager");
|
||||
}
|
||||
|
||||
// ------- FilePrototype
|
||||
|
||||
FilePrototype::FilePrototype(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
IFile *FilePrototype::callee() const
|
||||
{
|
||||
IFile *rc = qscriptvalue_cast<IFile *>(thisObject());
|
||||
QTC_ASSERT(rc, return 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
QString FilePrototype::fileName () const { return callee()->fileName(); }
|
||||
QString FilePrototype::defaultPath () const { return callee()->defaultPath(); }
|
||||
QString FilePrototype::suggestedFileName () const { return callee()->suggestedFileName(); }
|
||||
|
||||
bool FilePrototype::isModified () const { return callee()->isModified(); }
|
||||
bool FilePrototype::isReadOnly () const { return callee()->isReadOnly(); }
|
||||
bool FilePrototype::isSaveAsAllowed () const { return callee()->isSaveAsAllowed(); }
|
||||
|
||||
QString FilePrototype::toString() const
|
||||
{
|
||||
QString rc = QLatin1String("File(");
|
||||
rc += fileName();
|
||||
rc += QLatin1Char(')');
|
||||
return rc;
|
||||
}
|
||||
|
||||
// ------------- EditorManagerPrototype
|
||||
|
||||
EditorManagerPrototype::EditorManagerPrototype(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
Core::IEditor *EditorManagerPrototype::currentEditor() const
|
||||
{
|
||||
return callee()->currentEditor();
|
||||
}
|
||||
|
||||
void EditorManagerPrototype::activateEditor(Core::IEditor *editor)
|
||||
{
|
||||
callee()->activateEditor(editor);
|
||||
}
|
||||
|
||||
QList<Core::IEditor*> EditorManagerPrototype::openedEditors() const
|
||||
{
|
||||
return callee()->openedEditors();
|
||||
}
|
||||
|
||||
QList<Core::IEditor*> EditorManagerPrototype::editorsForFiles(QList<Core::IFile*> files) const
|
||||
{
|
||||
return callee()->editorsForFiles(files);
|
||||
}
|
||||
|
||||
bool EditorManagerPrototype::closeEditors(const QList<Core::IEditor*> editorsToClose, bool askAboutModifiedEditors)
|
||||
{
|
||||
return callee()->closeEditors(editorsToClose, askAboutModifiedEditors);
|
||||
}
|
||||
|
||||
Core::IEditor *EditorManagerPrototype::openEditor(const QString &fileName, const QString &editorKind)
|
||||
{
|
||||
return callee()->openEditor(fileName, editorKind);
|
||||
}
|
||||
|
||||
Core::IEditor *EditorManagerPrototype::newFile(const QString &editorKind, QString titlePattern, const QString &contents)
|
||||
{
|
||||
return callee()->openEditorWithContents(editorKind, &titlePattern, contents);
|
||||
}
|
||||
|
||||
int EditorManagerPrototype::makeEditorWritable(Core::IEditor *editor)
|
||||
{
|
||||
return callee()->makeEditorWritable(editor);
|
||||
}
|
||||
|
||||
QString EditorManagerPrototype::toString() const
|
||||
{
|
||||
return QLatin1String("EditorManager");
|
||||
}
|
||||
|
||||
EditorManagerPrototype::EditorManager *EditorManagerPrototype::callee() const
|
||||
{
|
||||
EditorManager *rc = qscriptvalue_cast<EditorManager *>(thisObject());
|
||||
QTC_ASSERT(rc, return 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// ------------- EditorPrototype
|
||||
|
||||
EditorPrototype::EditorPrototype(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QString EditorPrototype::displayName() const
|
||||
{
|
||||
return callee()->displayName();
|
||||
}
|
||||
|
||||
void EditorPrototype::setDisplayName(const QString &title)
|
||||
{
|
||||
callee()->setDisplayName(title);
|
||||
}
|
||||
|
||||
QString EditorPrototype::kind() const
|
||||
{
|
||||
return QLatin1String(callee()->kind());
|
||||
}
|
||||
|
||||
bool EditorPrototype::duplicateSupported() const
|
||||
{
|
||||
return callee()->duplicateSupported();
|
||||
}
|
||||
|
||||
bool EditorPrototype::createNew(const QString &contents)
|
||||
{
|
||||
return callee()->createNew(contents);
|
||||
}
|
||||
|
||||
bool EditorPrototype::open(const QString &fileName)
|
||||
{
|
||||
return callee()->open(fileName);
|
||||
}
|
||||
|
||||
Core::IEditor *EditorPrototype::duplicate(QWidget *parent)
|
||||
{
|
||||
return callee()->duplicate(parent);
|
||||
}
|
||||
|
||||
Core::IFile *EditorPrototype::file() const
|
||||
{
|
||||
return callee()->file();
|
||||
}
|
||||
|
||||
QWidget* EditorPrototype::toolBar() const
|
||||
{
|
||||
return callee()->toolBar();
|
||||
}
|
||||
|
||||
Core::IEditor *EditorPrototype::callee() const
|
||||
{
|
||||
IEditor *rc = qscriptvalue_cast<IEditor *>(thisObject());
|
||||
QTC_ASSERT(rc, return 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
QString EditorPrototype::toString() const
|
||||
{
|
||||
QString rc = QLatin1String("Editor(");
|
||||
rc += displayName();
|
||||
rc += QLatin1Char(')');
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
@ -1,228 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef QWORKBENCH_WRAPPER_H
|
||||
#define QWORKBENCH_WRAPPER_H
|
||||
|
||||
#include "metatypedeclarations.h" // required for property declarations
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QString>
|
||||
#include <QtScript/QScriptable>
|
||||
#include <QtScript/QScriptValue>
|
||||
|
||||
namespace Core {
|
||||
namespace Internal {
|
||||
|
||||
// Script prototype for the core interface.
|
||||
|
||||
class CorePrototype : public QObject, public QScriptable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(Core::MessageManager* messageManager READ messageManager DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(Core::FileManager* fileManager READ fileManager DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(Core::EditorManager* editorManager READ editorManager DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
|
||||
Q_PROPERTY(QMainWindow* mainWindow READ mainWindow DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(QSettings* settings READ settings DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
|
||||
public:
|
||||
typedef Core::ICore ICore;
|
||||
|
||||
CorePrototype(QObject *parent);
|
||||
|
||||
Core::MessageManager *messageManager() const;
|
||||
Core::FileManager *fileManager() const;
|
||||
Core::EditorManager *editorManager() const;
|
||||
|
||||
QMainWindow *mainWindow() const;
|
||||
QSettings *settings() const;
|
||||
|
||||
public slots:
|
||||
void addAdditionalContext(int context);
|
||||
void removeAdditionalContext(int context);
|
||||
QString toString() const;
|
||||
|
||||
private:
|
||||
ICore *callee() const;
|
||||
};
|
||||
|
||||
// Script prototype for the message manager.
|
||||
|
||||
class MessageManagerPrototype : public QObject, public QScriptable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
typedef Core::MessageManager MessageManager;
|
||||
|
||||
MessageManagerPrototype(QObject *parent = 0);
|
||||
|
||||
public slots:
|
||||
void displayStatusBarMessage(const QString &text, int ms = 0);
|
||||
void printToOutputPane(const QString &text, bool bringToForeground = true);
|
||||
QString toString() const;
|
||||
};
|
||||
|
||||
// Script prototype for the file manager interface.
|
||||
|
||||
class FileManagerPrototype : public QObject, public QScriptable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QStringList recentFiles READ recentFiles DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
|
||||
public:
|
||||
typedef Core::FileManager FileManager;
|
||||
|
||||
FileManagerPrototype(QObject *parent = 0);
|
||||
QStringList recentFiles() const;
|
||||
|
||||
public slots:
|
||||
bool addFiles(const QList<Core::IFile *> &files);
|
||||
bool addFile(Core::IFile *file);
|
||||
bool removeFile(Core::IFile *file);
|
||||
|
||||
QList<Core::IFile*> saveModifiedFilesSilently(const QList<Core::IFile*> &files);
|
||||
QString getSaveAsFileName(Core::IFile *file);
|
||||
|
||||
bool isFileManaged(const QString &fileName) const;
|
||||
QList<Core::IFile *> managedFiles(const QString &fileName) const;
|
||||
|
||||
void blockFileChange(Core::IFile *file);
|
||||
void unblockFileChange(Core::IFile *file);
|
||||
|
||||
void addToRecentFiles(const QString &fileName);
|
||||
QString toString() const;
|
||||
|
||||
private:
|
||||
FileManager *callee() const;
|
||||
};
|
||||
|
||||
// Script prototype for the file interface.
|
||||
|
||||
class FilePrototype : public QObject, public QScriptable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString fileName READ fileName DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(QString defaultPath READ defaultPath DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(QString suggestedFileName READ suggestedFileName DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(bool isModified READ isModified DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(bool isReadOnly READ isReadOnly DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(bool isSaveAsAllowed READ isSaveAsAllowed DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
public:
|
||||
typedef Core::IFile IFile;
|
||||
|
||||
FilePrototype(QObject *parent = 0);
|
||||
|
||||
QString fileName() const;
|
||||
QString defaultPath() const;
|
||||
QString suggestedFileName() const;
|
||||
|
||||
bool isModified() const;
|
||||
bool isReadOnly() const;
|
||||
bool isSaveAsAllowed() const;
|
||||
|
||||
public slots:
|
||||
QString toString() const;
|
||||
|
||||
private:
|
||||
IFile *callee() const;
|
||||
};
|
||||
|
||||
// Script prototype for the editor manager interface.
|
||||
|
||||
class EditorManagerPrototype : public QObject, public QScriptable
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(Core::IEditor* currentEditor READ currentEditor WRITE activateEditor DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(QList<Core::IEditor*> openedEditors READ openedEditors DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
public:
|
||||
typedef Core::EditorManager EditorManager;
|
||||
|
||||
EditorManagerPrototype(QObject *parent = 0);
|
||||
|
||||
Core::IEditor *currentEditor() const;
|
||||
void activateEditor(Core::IEditor *editor);
|
||||
QList<Core::IEditor*> openedEditors() const;
|
||||
QList<Core::IEditor*> editorHistory() const;
|
||||
|
||||
public slots:
|
||||
QList<Core::IEditor*> editorsForFiles(QList<Core::IFile*> files) const;
|
||||
bool closeEditors(const QList<Core::IEditor*> editorsToClose, bool askAboutModifiedEditors);
|
||||
Core::IEditor *openEditor(const QString &fileName, const QString &editorKind);
|
||||
Core::IEditor *newFile(const QString &editorKind, QString titlePattern, const QString &contents);
|
||||
int makeEditorWritable(Core::IEditor *editor);
|
||||
|
||||
QString toString() const;
|
||||
|
||||
private:
|
||||
EditorManager *callee() const;
|
||||
};
|
||||
|
||||
// Script prototype for the editor interface.
|
||||
|
||||
class EditorPrototype : public QObject, public QScriptable
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString displayName READ displayName WRITE setDisplayName DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(QString kind READ kind DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(bool duplicateSupported READ duplicateSupported DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(Core::IFile* file READ file DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(QWidget* toolBar READ toolBar DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
|
||||
public:
|
||||
EditorPrototype(QObject *parent = 0);
|
||||
|
||||
QString displayName() const;
|
||||
void setDisplayName(const QString &title);
|
||||
|
||||
QString kind() const;
|
||||
bool duplicateSupported() const;
|
||||
|
||||
Core::IFile *file() const;
|
||||
QWidget* toolBar() const;
|
||||
|
||||
public slots:
|
||||
bool createNew(const QString &contents);
|
||||
bool open(const QString &fileName);
|
||||
Core::IEditor *duplicate(QWidget *parent);
|
||||
|
||||
QString toString() const;
|
||||
|
||||
private:
|
||||
Core::IEditor *callee() const;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
#endif // QWORKBENCH_WRAPPER_H
|
@ -1,298 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "scriptmanager_p.h"
|
||||
#include "qworkbench_wrapper.h"
|
||||
#include "metatypedeclarations.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <interface_wrap_helpers.h>
|
||||
#include <wrap_helpers.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QInputDialog>
|
||||
#include <QtGui/QFileDialog>
|
||||
#include <QtGui/QMainWindow>
|
||||
#include <QtGui/QToolBar>
|
||||
#include <QtGui/QStatusBar>
|
||||
|
||||
// Script function template to pop up a message box
|
||||
// with a certain icon and buttons.
|
||||
template <int MsgBoxIcon, int MsgBoxButtons>
|
||||
static QScriptValue messageBox(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
if (context->argumentCount() < 3)
|
||||
return QScriptValue(engine, -1);
|
||||
|
||||
QWidget *parent = qscriptvalue_cast<QWidget *>(context->argument(0));
|
||||
const QString title = context->argument(1).toString();
|
||||
const QString msg = context->argument(2).toString();
|
||||
|
||||
QMessageBox msgBox(static_cast<QMessageBox::Icon>(MsgBoxIcon), title, msg,
|
||||
static_cast<QMessageBox::StandardButtons>(MsgBoxButtons), parent);
|
||||
|
||||
return QScriptValue(engine, msgBox.exec());
|
||||
}
|
||||
|
||||
static QScriptValue inputDialogGetText(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
const int argumentCount = context->argumentCount();
|
||||
if (argumentCount < 3)
|
||||
return QScriptValue(engine, QScriptValue::NullValue);
|
||||
|
||||
QWidget *parent = qscriptvalue_cast<QWidget *>(context->argument(0));
|
||||
const QString title = context->argument(1).toString();
|
||||
const QString label = context->argument(2).toString();
|
||||
const QString defaultValue = argumentCount > 3 ? context->argument(3).toString() : QString();
|
||||
|
||||
bool ok;
|
||||
const QString rc = QInputDialog::getText(parent, title, label, QLineEdit::Normal, defaultValue, &ok);
|
||||
if (!ok)
|
||||
return QScriptValue(engine, QScriptValue::NullValue);
|
||||
return QScriptValue(engine, rc);
|
||||
}
|
||||
|
||||
static QScriptValue inputDialogGetInteger(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
const int argumentCount = context->argumentCount();
|
||||
if (argumentCount < 3)
|
||||
return QScriptValue(engine, QScriptValue::NullValue);
|
||||
|
||||
QWidget *parent = qscriptvalue_cast<QWidget *>(context->argument(0));
|
||||
const QString title = context->argument(1).toString();
|
||||
const QString label = context->argument(2).toString();
|
||||
const int defaultValue = argumentCount > 3 ? context->argument(3).toInt32() : 0;
|
||||
const int minValue = argumentCount > 4 ? context->argument(4).toInt32() : INT_MIN;
|
||||
const int maxValue = argumentCount > 5 ? context->argument(5).toInt32() : INT_MAX;
|
||||
|
||||
bool ok;
|
||||
const int rc = QInputDialog::getInteger(parent, title, label, defaultValue, minValue, maxValue, 1, &ok);
|
||||
if (!ok)
|
||||
return QScriptValue(engine, QScriptValue::NullValue);
|
||||
return QScriptValue(engine, rc);
|
||||
}
|
||||
|
||||
static QScriptValue inputDialogGetDouble(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
const int argumentCount = context->argumentCount();
|
||||
if (argumentCount < 3)
|
||||
return QScriptValue(engine, QScriptValue::NullValue);
|
||||
|
||||
QWidget *parent = qscriptvalue_cast<QWidget *>(context->argument(0));
|
||||
const QString title = context->argument(1).toString();
|
||||
const QString label = context->argument(2).toString();
|
||||
const double defaultValue = argumentCount > 3 ? context->argument(3).toNumber() : 0;
|
||||
// Use QInputDialog defaults
|
||||
const double minValue = argumentCount > 4 ? context->argument(4).toNumber() : INT_MIN;
|
||||
const double maxValue = argumentCount > 5 ? context->argument(5).toNumber() : INT_MAX;
|
||||
|
||||
bool ok;
|
||||
const double rc = QInputDialog::getDouble(parent, title, label, defaultValue, minValue, maxValue, 1, &ok);
|
||||
if (!ok)
|
||||
return QScriptValue(engine, QScriptValue::NullValue);
|
||||
return QScriptValue(engine, rc);
|
||||
}
|
||||
|
||||
static QScriptValue inputDialogGetItem(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
const int argumentCount = context->argumentCount();
|
||||
if (argumentCount < 4)
|
||||
return QScriptValue(engine, QScriptValue::NullValue);
|
||||
|
||||
QWidget *parent = qscriptvalue_cast<QWidget *>(context->argument(0));
|
||||
const QString title = context->argument(1).toString();
|
||||
const QString label = context->argument(2).toString();
|
||||
const QStringList items = qscriptvalue_cast<QStringList>(context->argument(3));
|
||||
const int defaultItem = argumentCount > 4 ? context->argument(4).toInt32() : 0;
|
||||
const bool editable = argumentCount > 5 ? context->argument(5).toInt32() : 0;
|
||||
|
||||
bool ok;
|
||||
const QString rc = QInputDialog::getItem (parent, title, label, items, defaultItem, editable, &ok);
|
||||
if (!ok)
|
||||
return QScriptValue(engine, QScriptValue::NullValue);
|
||||
|
||||
return QScriptValue(engine, rc);
|
||||
}
|
||||
|
||||
// Script function template to pop up a file box
|
||||
// with a certain icon and buttons.
|
||||
template <int TAcceptMode, int TFileMode>
|
||||
static QScriptValue fileBox(QScriptContext *context, QScriptEngine *engine)
|
||||
{
|
||||
const int argumentCount = context->argumentCount();
|
||||
if (argumentCount < 2)
|
||||
return QScriptValue(engine, QScriptValue::NullValue);
|
||||
|
||||
QWidget *parent = qscriptvalue_cast<QWidget *>(context->argument(0));
|
||||
const QString title = context->argument(1).toString();
|
||||
const QString directory = argumentCount > 2 ? context->argument(2).toString() : QString();
|
||||
const QString filter = argumentCount > 3 ? context->argument(3).toString() : QString();
|
||||
QFileDialog fileDialog(parent, title, directory, filter);
|
||||
fileDialog.setAcceptMode(static_cast<QFileDialog::AcceptMode>(TAcceptMode));
|
||||
fileDialog.setFileMode (static_cast<QFileDialog::FileMode>(TFileMode));
|
||||
if (fileDialog.exec() == QDialog::Rejected)
|
||||
return QScriptValue(engine, QScriptValue::NullValue);
|
||||
const QStringList rc = fileDialog.selectedFiles();
|
||||
QTC_ASSERT(!rc.empty(), /**/);
|
||||
return TFileMode == QFileDialog::ExistingFiles ?
|
||||
engine->toScriptValue(rc) : engine->toScriptValue(rc.front());
|
||||
}
|
||||
|
||||
// ------ ScriptManagerPrivate
|
||||
|
||||
namespace Core {
|
||||
namespace Internal {
|
||||
|
||||
ScriptManagerPrivate::ScriptManagerPrivate(QObject *parent)
|
||||
: ScriptManager(parent),
|
||||
m_engine(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Split a backtrace of the form:
|
||||
// "<anonymous>(BuildManagerCommand(ls))@:0
|
||||
// demoProjectExplorer()@:237
|
||||
// <anonymous>()@:276
|
||||
// <global>()@:0"
|
||||
static void parseBackTrace(const QStringList &backTrace, ScriptManagerPrivate::Stack &stack)
|
||||
{
|
||||
const QChar at = QLatin1Char('@');
|
||||
const QChar colon = QLatin1Char(':');
|
||||
stack.clear();
|
||||
foreach (const QString &line, backTrace) {
|
||||
const int atPos = line.lastIndexOf(at);
|
||||
if (atPos == -1)
|
||||
continue;
|
||||
const int colonPos = line.indexOf(colon, atPos + 1);
|
||||
if (colonPos == -1)
|
||||
continue;
|
||||
|
||||
ScriptManagerPrivate::StackFrame frame;
|
||||
frame.function = line.left(atPos);
|
||||
frame.fileName = line.mid(atPos + 1, colonPos - atPos - 1);
|
||||
frame.lineNumber = line.right(line.size() - colonPos - 1).toInt();
|
||||
stack.push_back(frame);
|
||||
}
|
||||
}
|
||||
|
||||
bool ScriptManagerPrivate::runScript(const QString &script, QString *errorMessage)
|
||||
{
|
||||
Stack stack;
|
||||
return runScript(script, errorMessage, &stack);
|
||||
}
|
||||
|
||||
bool ScriptManagerPrivate::runScript(const QString &script, QString *errorMessage, Stack *stack)
|
||||
{
|
||||
ensureEngineInitialized();
|
||||
stack->clear();
|
||||
|
||||
m_engine->pushContext();
|
||||
m_engine->evaluate(script);
|
||||
|
||||
const bool failed = m_engine->hasUncaughtException ();
|
||||
if (failed) {
|
||||
const int errorLineNumber = m_engine->uncaughtExceptionLineNumber();
|
||||
const QStringList backTrace = m_engine->uncaughtExceptionBacktrace();
|
||||
parseBackTrace(backTrace, *stack);
|
||||
const QString backtrace = backTrace.join(QString(QLatin1Char('\n')));
|
||||
*errorMessage = ScriptManager::tr("Exception at line %1: %2\n%3").arg(errorLineNumber).arg(engineError(m_engine)).arg(backtrace);
|
||||
}
|
||||
m_engine->popContext();
|
||||
return !failed;
|
||||
}
|
||||
|
||||
void ScriptManagerPrivate::ensureEngineInitialized()
|
||||
{
|
||||
if (m_engine)
|
||||
return;
|
||||
m_engine = new QScriptEngine(this);
|
||||
// register QObjects that occur as properties
|
||||
SharedTools::registerQObject<QMainWindow>(m_engine);
|
||||
SharedTools::registerQObject<QStatusBar>(m_engine);
|
||||
SharedTools::registerQObject<QSettings>(m_engine);
|
||||
// WB interfaces
|
||||
// SharedTools::registerQObjectInterface<Core::MessageManager, MessageManagerPrototype>(m_engine);
|
||||
|
||||
// SharedTools::registerQObjectInterface<Core::IFile, FilePrototype>(m_engine);
|
||||
// qScriptRegisterSequenceMetaType<QList<Core::IFile *> >(m_engine);
|
||||
// SharedTools::registerQObjectInterface<Core::FileManager, FileManagerPrototype>(m_engine);
|
||||
|
||||
// SharedTools::registerQObjectInterface<Core::IEditor, EditorPrototype>(m_engine);
|
||||
qScriptRegisterSequenceMetaType<QList<Core::IEditor *> >(m_engine);
|
||||
|
||||
// SharedTools::registerQObjectInterface<Core::EditorGroup, EditorGroupPrototype>(m_engine);
|
||||
qScriptRegisterSequenceMetaType<QList<Core::EditorGroup *> >(m_engine);
|
||||
|
||||
SharedTools::registerQObjectInterface<Core::EditorManager, EditorManagerPrototype>(m_engine);
|
||||
|
||||
// SharedTools::registerQObjectInterface<Core::ICore, CorePrototype>(m_engine);
|
||||
|
||||
// Make "core" available
|
||||
m_engine->globalObject().setProperty(QLatin1String("core"), qScriptValueFromValue(m_engine, Core::ICore::instance()));
|
||||
|
||||
// CLASSIC: registerInterfaceWithDefaultPrototype<Core::MessageManager, MessageManagerPrototype>(m_engine);
|
||||
|
||||
// Message box conveniences
|
||||
m_engine->globalObject().setProperty(QLatin1String("critical"),
|
||||
m_engine->newFunction(messageBox<QMessageBox::Critical, QMessageBox::Ok>, 3));
|
||||
m_engine->globalObject().setProperty(QLatin1String("warning"),
|
||||
m_engine->newFunction(messageBox<QMessageBox::Warning, QMessageBox::Ok>, 3));
|
||||
m_engine->globalObject().setProperty(QLatin1String("information"),
|
||||
m_engine->newFunction(messageBox<QMessageBox::Information, QMessageBox::Ok>, 3));
|
||||
// StandardButtons has overloaded operator '|' - grrr.
|
||||
enum { MsgBoxYesNo = 0x00014000 };
|
||||
m_engine->globalObject().setProperty(QLatin1String("yesNoQuestion"),
|
||||
m_engine->newFunction(messageBox<QMessageBox::Question, MsgBoxYesNo>, 3));
|
||||
|
||||
m_engine->globalObject().setProperty(QLatin1String("getText"), m_engine->newFunction(inputDialogGetText, 3));
|
||||
m_engine->globalObject().setProperty(QLatin1String("getInteger"), m_engine->newFunction(inputDialogGetInteger, 3));
|
||||
m_engine->globalObject().setProperty(QLatin1String("getDouble"), m_engine->newFunction(inputDialogGetDouble, 3));
|
||||
m_engine->globalObject().setProperty(QLatin1String("getItem"), m_engine->newFunction(inputDialogGetItem, 3));
|
||||
|
||||
// file box
|
||||
m_engine->globalObject().setProperty(QLatin1String("getOpenFileNames"), m_engine->newFunction(fileBox<QFileDialog::AcceptOpen, QFileDialog::ExistingFiles> , 2));
|
||||
m_engine->globalObject().setProperty(QLatin1String("getOpenFileName"), m_engine->newFunction(fileBox<QFileDialog::AcceptOpen, QFileDialog::ExistingFile> , 2));
|
||||
m_engine->globalObject().setProperty(QLatin1String("getSaveFileName"), m_engine->newFunction(fileBox<QFileDialog::AcceptSave, QFileDialog::AnyFile> , 2));
|
||||
m_engine->globalObject().setProperty(QLatin1String("getExistingDirectory"), m_engine->newFunction(fileBox<QFileDialog::AcceptSave, QFileDialog::DirectoryOnly> , 2));
|
||||
}
|
||||
|
||||
QString ScriptManagerPrivate::engineError(QScriptEngine *scriptEngine)
|
||||
{
|
||||
QScriptValue error = scriptEngine->evaluate(QLatin1String("Error"));
|
||||
if (error.isValid())
|
||||
return error.toString();
|
||||
return ScriptManager::tr("Unknown error");
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
@ -1,69 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SCRIPTMANAGER_H
|
||||
#define SCRIPTMANAGER_H
|
||||
|
||||
#include <coreplugin/core_global.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QString>
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
namespace Core {
|
||||
|
||||
/* Script Manager.
|
||||
* Provides a script engine that is initialized with
|
||||
* Qt Creator's interfaces and allows for running scripts.
|
||||
* @{todo} Should it actually manage script files, too? */
|
||||
|
||||
class CORE_EXPORT ScriptManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// A stack frame as returned by a failed invocation (exception)
|
||||
// fileName may be empty. lineNumber can be 0 for the top frame (goof-up?).
|
||||
struct StackFrame {
|
||||
QString function;
|
||||
QString fileName;
|
||||
int lineNumber;
|
||||
};
|
||||
typedef QList<StackFrame> Stack;
|
||||
|
||||
ScriptManager(QObject *parent = 0) : QObject(parent) {}
|
||||
virtual ~ScriptManager() { }
|
||||
|
||||
// Run a script
|
||||
virtual bool runScript(const QString &script, QString *errorMessage, Stack *errorStack) = 0;
|
||||
virtual bool runScript(const QString &script, QString *errorMessage) = 0;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif // SCRIPTMANAGER_H
|
@ -1,62 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SCRIPTMANAGER_P_H
|
||||
#define SCRIPTMANAGER_P_H
|
||||
|
||||
#include <coreplugin/scriptmanager/scriptmanager.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
namespace Core {
|
||||
namespace Internal {
|
||||
|
||||
class ScriptManagerPrivate : public Core::ScriptManager
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ScriptManagerPrivate(QObject *parent);
|
||||
|
||||
bool runScript(const QString &script, QString *errorMessage, Stack *stack);
|
||||
bool runScript(const QString &script, QString *errorMessage);
|
||||
|
||||
static QString engineError(QScriptEngine *scriptEngine);
|
||||
|
||||
private:
|
||||
void ensureEngineInitialized();
|
||||
|
||||
QScriptEngine *m_engine;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
#endif // SCRIPTMANAGER_P_H
|
@ -1,155 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "vcsmanager.h"
|
||||
#include "iversioncontrol.h"
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtGui/QMessageBox>
|
||||
|
||||
enum { debug = 0 };
|
||||
|
||||
namespace Core {
|
||||
|
||||
typedef QList<IVersionControl *> VersionControlList;
|
||||
|
||||
static inline VersionControlList allVersionControls()
|
||||
{
|
||||
return ExtensionSystem::PluginManager::instance()->getObjects<IVersionControl>();
|
||||
}
|
||||
|
||||
// ---- VCSManagerPrivate
|
||||
struct VCSManagerPrivate {
|
||||
QMap<QString, IVersionControl *> m_cachedMatches;
|
||||
};
|
||||
|
||||
VCSManager::VCSManager(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_d(new VCSManagerPrivate)
|
||||
{
|
||||
}
|
||||
|
||||
VCSManager::~VCSManager()
|
||||
{
|
||||
delete m_d;
|
||||
}
|
||||
|
||||
void VCSManager::extensionsInitialized()
|
||||
{
|
||||
// Change signal connections
|
||||
foreach (IVersionControl *versionControl, allVersionControls()) {
|
||||
connect(versionControl, SIGNAL(filesChanged(QStringList)),
|
||||
this, SIGNAL(filesChanged(QStringList)));
|
||||
connect(versionControl, SIGNAL(repositoryChanged(QString)),
|
||||
this, SIGNAL(repositoryChanged(QString)));
|
||||
}
|
||||
}
|
||||
|
||||
void VCSManager::setVCSEnabled(const QString &directory)
|
||||
{
|
||||
if (debug)
|
||||
qDebug() << Q_FUNC_INFO << directory;
|
||||
IVersionControl* managingVCS = findVersionControlForDirectory(directory);
|
||||
const VersionControlList versionControls = allVersionControls();
|
||||
foreach (IVersionControl *versionControl, versionControls) {
|
||||
const bool newEnabled = versionControl == managingVCS;
|
||||
if (newEnabled != versionControl->isEnabled())
|
||||
versionControl->setEnabled(newEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
void VCSManager::setAllVCSEnabled()
|
||||
{
|
||||
if (debug)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
const VersionControlList versionControls = allVersionControls();
|
||||
foreach (IVersionControl *versionControl, versionControls)
|
||||
if (!versionControl->isEnabled())
|
||||
versionControl->setEnabled(true);
|
||||
}
|
||||
|
||||
IVersionControl* VCSManager::findVersionControlForDirectory(const QString &directory)
|
||||
{
|
||||
// first look into the cache, check the whole name
|
||||
|
||||
{
|
||||
const QMap<QString, IVersionControl *>::const_iterator it = m_d->m_cachedMatches.constFind(directory);
|
||||
if (it != m_d->m_cachedMatches.constEnd())
|
||||
return it.value();
|
||||
}
|
||||
|
||||
int pos = 0;
|
||||
const QChar slash = QLatin1Char('/');
|
||||
while (true) {
|
||||
int index = directory.indexOf(slash, pos);
|
||||
if (index == -1)
|
||||
break;
|
||||
const QString directoryPart = directory.left(index);
|
||||
QMap<QString, IVersionControl *>::const_iterator it = m_d->m_cachedMatches.constFind(directoryPart);
|
||||
if (it != m_d->m_cachedMatches.constEnd())
|
||||
return it.value();
|
||||
pos = index+1;
|
||||
}
|
||||
|
||||
// ah nothing so ask the IVersionControls directly
|
||||
const VersionControlList versionControls = allVersionControls();
|
||||
foreach (IVersionControl * versionControl, versionControls) {
|
||||
if (versionControl->managesDirectory(directory)) {
|
||||
m_d->m_cachedMatches.insert(versionControl->findTopLevelForDirectory(directory), versionControl);
|
||||
return versionControl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool VCSManager::showDeleteDialog(const QString &fileName)
|
||||
{
|
||||
IVersionControl *vc = findVersionControlForDirectory(QFileInfo(fileName).absolutePath());
|
||||
if (!vc || !vc->supportsOperation(IVersionControl::DeleteOperation))
|
||||
return true;
|
||||
const QString title = QCoreApplication::translate("VCSManager", "Version Control");
|
||||
const QString msg = QCoreApplication::translate("VCSManager",
|
||||
"Would you like to remove this file from the version control system (%1)?\n"
|
||||
"Note: This might remove the local file.").arg(vc->name());
|
||||
const QMessageBox::StandardButton button =
|
||||
QMessageBox::question(0, title, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
|
||||
if (button != QMessageBox::Yes)
|
||||
return true;
|
||||
return vc->vcsDelete(fileName);
|
||||
}
|
||||
|
||||
} // namespace Core
|
@ -1,86 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef VCSMANAGER_H
|
||||
#define VCSMANAGER_H
|
||||
|
||||
#include "core_global.h"
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QObject>
|
||||
|
||||
namespace Core {
|
||||
|
||||
struct VCSManagerPrivate;
|
||||
class IVersionControl;
|
||||
|
||||
// The VCSManager has only one notable function:
|
||||
// findVersionControlFor(), which returns the IVersionControl * for a given
|
||||
// filename. Note that the VCSManager assumes that if a IVersionControl *
|
||||
// manages a directory, then it also manages all the files and all the
|
||||
// subdirectories.
|
||||
//
|
||||
// It works by asking all IVersionControl * if they manage the file, and ask
|
||||
// for the topmost directory it manages. This information is cached and
|
||||
// VCSManager thus knows pretty fast which IVersionControl * is responsible.
|
||||
|
||||
class CORE_EXPORT VCSManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(VCSManager)
|
||||
public:
|
||||
explicit VCSManager(QObject *parent = 0);
|
||||
virtual ~VCSManager();
|
||||
|
||||
void extensionsInitialized();
|
||||
|
||||
IVersionControl *findVersionControlForDirectory(const QString &directory);
|
||||
|
||||
// Enable the VCS managing a certain directory only. This should
|
||||
// be used by project manager classes.
|
||||
void setVCSEnabled(const QString &directory);
|
||||
// Enable all VCS.
|
||||
void setAllVCSEnabled();
|
||||
|
||||
// Shows a confirmation dialog, whether the file should also be deleted
|
||||
// from revision control Calls sccDelete on the file. Returns false
|
||||
// if a failure occurs
|
||||
bool showDeleteDialog(const QString &fileName);
|
||||
|
||||
signals:
|
||||
void repositoryChanged(const QString &repository);
|
||||
void filesChanged(const QStringList &files);
|
||||
|
||||
private:
|
||||
VCSManagerPrivate *m_d;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif // VCSMANAGER_H
|
Loading…
Reference in New Issue
Block a user