1
0
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:
julien 2010-02-28 10:52:10 +00:00 committed by julien
parent 557f33fe49
commit d09d755253
50 changed files with 0 additions and 11153 deletions

View File

@ -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();
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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
*/

View File

@ -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

View File

@ -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

View File

@ -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.
*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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()
{
}

View File

@ -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

View File

@ -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>

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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 */)
{
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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));
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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

View File

@ -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));
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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