forked from qt-creator/qt-creator
first edition of the new editor view, splitting still missing
This commit is contained in:
@@ -132,7 +132,6 @@ const char * const REMOVE = "QtCreator.Remove";
|
||||
const char * const SAVEASDEFAULT = "QtCreator.SaveAsDefaultLayout";
|
||||
const char * const RESTOREDEFAULT = "QtCreator.RestoreDefaultLayout";
|
||||
const char * const CLOSE = "QtCreator.Close";
|
||||
const char * const DUPLICATEDOCUMENT = "QtCreator.DuplicateDocument";
|
||||
const char * const CLOSEALL = "QtCreator.CloseAll";
|
||||
const char * const GOTONEXT = "QtCreator.GotoNext";
|
||||
const char * const GOTOPREV = "QtCreator.GotoPrevious";
|
||||
|
||||
@@ -36,6 +36,7 @@ SOURCES += mainwindow.cpp \
|
||||
versiondialog.cpp \
|
||||
editormanager/editorgroup.cpp \
|
||||
editormanager/editormanager.cpp \
|
||||
editormanager/editorview.cpp \
|
||||
editormanager/stackededitorgroup.cpp \
|
||||
editormanager/editorsplitter.cpp \
|
||||
editormanager/openeditorsview.cpp \
|
||||
@@ -92,6 +93,7 @@ HEADERS += mainwindow.h \
|
||||
viewmanager.h \
|
||||
editormanager/editorgroup.h \
|
||||
editormanager/editormanager.h \
|
||||
editormanager/editorview.h \
|
||||
editormanager/stackededitorgroup.h \
|
||||
editormanager/editorsplitter.h \
|
||||
editormanager/openeditorsview.h \
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "editorgroup.h"
|
||||
|
||||
#include "editormanager.h"
|
||||
|
||||
#include "editorview.h"
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
@@ -84,105 +84,6 @@ private:
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
//================EditorModel====================
|
||||
int EditorModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EditorModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
return m_editors.count();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EditorModel::insertEditor(int index, IEditor *editor)
|
||||
{
|
||||
beginInsertRows(QModelIndex(), index, index);
|
||||
m_editors.insert(index, editor);
|
||||
connect(editor, SIGNAL(changed()), this, SLOT(itemChanged()));
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void EditorModel::removeEditor(IEditor *editor)
|
||||
{
|
||||
int idx = m_editors.indexOf(editor);
|
||||
if (idx < 0)
|
||||
return;
|
||||
beginRemoveRows(QModelIndex(), idx, idx);
|
||||
m_editors.removeAt(idx);
|
||||
endRemoveRows();
|
||||
disconnect(editor, SIGNAL(changed()), this, SLOT(itemChanged()));
|
||||
}
|
||||
|
||||
|
||||
void EditorModel::emitDataChanged(IEditor *editor)
|
||||
{
|
||||
int idx = m_editors.indexOf(editor);
|
||||
if (idx < 0)
|
||||
return;
|
||||
QModelIndex mindex = index(idx, 0);
|
||||
emit dataChanged(mindex, mindex);
|
||||
}
|
||||
|
||||
QModelIndex EditorModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
if (column != 0 || row < 0 || row >= m_editors.count())
|
||||
return QModelIndex();
|
||||
return createIndex(row, column);
|
||||
}
|
||||
|
||||
QVariant EditorModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
IEditor *editor = m_editors.at(index.row());
|
||||
QTC_ASSERT(editor, return QVariant());
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
return editor->file()->isModified()
|
||||
? editor->displayName() + QLatin1String("*")
|
||||
: editor->displayName();
|
||||
case Qt::DecorationRole:
|
||||
return editor->file()->isReadOnly()
|
||||
? QIcon(QLatin1String(":/core/images/locked.png"))
|
||||
: QIcon();
|
||||
case Qt::ToolTipRole:
|
||||
return editor->file()->fileName().isEmpty()
|
||||
? editor->displayName()
|
||||
: QDir::toNativeSeparators(editor->file()->fileName());
|
||||
case Qt::UserRole:
|
||||
return qVariantFromValue(editor);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex EditorModel::indexOf(IEditor *editor) const
|
||||
{
|
||||
int idx = m_editors.indexOf(editor);
|
||||
if (idx < 0)
|
||||
return indexOf(editor->file()->fileName());
|
||||
return createIndex(idx, 0);
|
||||
}
|
||||
|
||||
QModelIndex EditorModel::indexOf(const QString &fileName) const
|
||||
{
|
||||
for (int i = 0; i < m_editors.count(); ++i)
|
||||
if (m_editors.at(i)->file()->fileName() == fileName)
|
||||
return createIndex(i, 0);
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
|
||||
void EditorModel::itemChanged()
|
||||
{
|
||||
emitDataChanged(qobject_cast<IEditor*>(sender()));
|
||||
}
|
||||
|
||||
//================EditorGroupContext===============
|
||||
|
||||
|
||||
@@ -124,33 +124,6 @@ private:
|
||||
|
||||
namespace Internal {
|
||||
|
||||
// Also used by StackedEditorGroup
|
||||
class EditorModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
EditorModel(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) { insertEditor(rowCount(), editor); }
|
||||
|
||||
void insertEditor(int index, IEditor *editor);
|
||||
void removeEditor(IEditor *editor);
|
||||
void emitDataChanged(IEditor *editor);
|
||||
|
||||
QList<IEditor *> editors() const { return m_editors; }
|
||||
QModelIndex indexOf(IEditor *editor) const;
|
||||
QModelIndex indexOf(const QString &filename) const;
|
||||
|
||||
private slots:
|
||||
void itemChanged();
|
||||
private:
|
||||
QList<IEditor *> m_editors;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Core
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "editormanager.h"
|
||||
#include "editorsplitter.h"
|
||||
#include "editorview.h"
|
||||
#include "openeditorswindow.h"
|
||||
#include "openwithdialog.h"
|
||||
#include "filemanager.h"
|
||||
@@ -128,7 +128,7 @@ struct EditorManagerPrivate {
|
||||
};
|
||||
explicit EditorManagerPrivate(ICore *core, QWidget *parent);
|
||||
~EditorManagerPrivate();
|
||||
Internal::EditorSplitter *m_splitter;
|
||||
Internal::EditorView *m_view;
|
||||
ICore *m_core;
|
||||
|
||||
bool m_suppressEditorChanges;
|
||||
@@ -141,7 +141,6 @@ struct EditorManagerPrivate {
|
||||
QAction *m_closeAllEditorsAction;
|
||||
QAction *m_gotoNextDocHistoryAction;
|
||||
QAction *m_gotoPreviousDocHistoryAction;
|
||||
QAction *m_duplicateAction;
|
||||
QAction *m_goBackAction;
|
||||
QAction *m_goForwardAction;
|
||||
QAction *m_openInExternalEditorAction;
|
||||
@@ -153,9 +152,6 @@ struct EditorManagerPrivate {
|
||||
Core::BaseView *m_openEditorsView;
|
||||
Internal::EditorClosingCoreListener *m_coreListener;
|
||||
|
||||
typedef QMap<IEditor *, QList<IEditor *> *> DuplicateMap;
|
||||
DuplicateMap m_duplicates;
|
||||
|
||||
QMap<QString, QVariant> m_editorStates;
|
||||
Internal::OpenEditorsViewFactory *m_openEditorsFactory;
|
||||
|
||||
@@ -168,7 +164,7 @@ struct EditorManagerPrivate {
|
||||
}
|
||||
|
||||
EditorManagerPrivate::EditorManagerPrivate(ICore *core, QWidget *parent) :
|
||||
m_splitter(0),
|
||||
m_view(0),
|
||||
m_core(core),
|
||||
m_suppressEditorChanges(false),
|
||||
m_revertToSavedAction(new QAction(EditorManager::tr("Revert to Saved"), parent)),
|
||||
@@ -178,7 +174,6 @@ EditorManagerPrivate::EditorManagerPrivate(ICore *core, QWidget *parent) :
|
||||
m_closeAllEditorsAction(new QAction(EditorManager::tr("Close All"), parent)),
|
||||
m_gotoNextDocHistoryAction(new QAction(EditorManager::tr("Next Document in History"), parent)),
|
||||
m_gotoPreviousDocHistoryAction(new QAction(EditorManager::tr("Previous Document in History"), parent)),
|
||||
m_duplicateAction(new QAction(EditorManager::tr("Duplicate Document"), parent)),
|
||||
m_goBackAction(new QAction(EditorManager::tr("Go back"), parent)),
|
||||
m_goForwardAction(new QAction(EditorManager::tr("Go forward"), parent)),
|
||||
m_openInExternalEditorAction(new QAction(EditorManager::tr("Open in External Editor"), parent)),
|
||||
@@ -272,11 +267,6 @@ EditorManager::EditorManager(ICore *core, QWidget *parent) :
|
||||
mfile->addAction(cmd, Constants::G_FILE_CLOSE);
|
||||
connect(m_d->m_closeAllEditorsAction, SIGNAL(triggered()), this, SLOT(closeAllEditors()));
|
||||
|
||||
//Duplicate Action
|
||||
cmd = am->registerAction(m_d->m_duplicateAction, Constants::DUPLICATEDOCUMENT, editManagerContext);
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_CLOSE);
|
||||
connect(m_d->m_duplicateAction, SIGNAL(triggered()), this, SLOT(duplicateEditor()));
|
||||
|
||||
// Goto Previous In History Action
|
||||
cmd = am->registerAction(m_d->m_gotoPreviousDocHistoryAction, Constants::GOTOPREVINHISTORY, editManagerContext);
|
||||
#ifdef Q_WS_MAC
|
||||
@@ -334,16 +324,14 @@ EditorManager::EditorManager(ICore *core, QWidget *parent) :
|
||||
this, SLOT(updateActions()));
|
||||
connect(this, SIGNAL(currentEditorChanged(Core::IEditor*)),
|
||||
this, SLOT(updateEditorHistory()));
|
||||
m_d->m_splitter = new EditorSplitter(m_d->m_core);
|
||||
connect(m_d->m_splitter, SIGNAL(closeRequested(Core::IEditor *)),
|
||||
m_d->m_view = new EditorView(m_d->m_editorModel, this);
|
||||
connect(m_d->m_view, SIGNAL(closeRequested(Core::IEditor *)),
|
||||
this, SLOT(closeEditor(Core::IEditor *)));
|
||||
connect(m_d->m_splitter, SIGNAL(editorGroupsChanged()),
|
||||
this, SIGNAL(editorGroupsChanged()));
|
||||
|
||||
QHBoxLayout *l = new QHBoxLayout(this);
|
||||
l->setSpacing(0);
|
||||
l->setMargin(0);
|
||||
l->addWidget(m_d->m_splitter);
|
||||
l->addWidget(m_d->m_view);
|
||||
|
||||
updateActions();
|
||||
|
||||
@@ -394,11 +382,6 @@ QString EditorManager::defaultExternalEditor() const
|
||||
#endif
|
||||
}
|
||||
|
||||
EditorSplitter *EditorManager::editorSplitter() const
|
||||
{
|
||||
return m_d->m_splitter;
|
||||
}
|
||||
|
||||
void EditorManager::updateEditorHistory()
|
||||
{
|
||||
IEditor *editor = currentEditor();
|
||||
@@ -412,10 +395,9 @@ bool EditorManager::registerEditor(IEditor *editor)
|
||||
{
|
||||
if (editor) {
|
||||
m_d->m_editorModel->addEditor(editor);
|
||||
if (!hasDuplicate(editor)) {
|
||||
m_d->m_core->fileManager()->addFile(editor->file());
|
||||
m_d->m_core->fileManager()->addToRecentFiles(editor->file()->fileName());
|
||||
}
|
||||
m_d->m_core->fileManager()->addFile(editor->file());
|
||||
m_d->m_core->fileManager()->addToRecentFiles(editor->file()->fileName());
|
||||
|
||||
m_d->m_editorHistory.removeAll(editor);
|
||||
m_d->m_editorHistory.prepend(editor);
|
||||
return true;
|
||||
@@ -427,8 +409,7 @@ bool EditorManager::unregisterEditor(IEditor *editor)
|
||||
{
|
||||
if (editor) {
|
||||
m_d->m_editorModel->removeEditor(editor);
|
||||
if (!hasDuplicate(editor))
|
||||
m_d->m_core->fileManager()->removeFile(editor->file());
|
||||
m_d->m_core->fileManager()->removeFile(editor->file());
|
||||
m_d->m_editorHistory.removeAll(editor);
|
||||
return true;
|
||||
}
|
||||
@@ -439,13 +420,8 @@ void EditorManager::updateCurrentEditorAndGroup(IContext *context)
|
||||
{
|
||||
if (debugEditorManager)
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
EditorGroupContext *groupContext = context ? qobject_cast<EditorGroupContext*>(context) : 0;
|
||||
IEditor *editor = context ? qobject_cast<IEditor*>(context) : 0;
|
||||
if (groupContext) {
|
||||
m_d->m_splitter->setCurrentGroup(groupContext->editorGroup());
|
||||
setCurrentEditor(0);
|
||||
updateActions();
|
||||
} else if (editor) {
|
||||
if (editor) {
|
||||
setCurrentEditor(editor);
|
||||
} else {
|
||||
updateActions();
|
||||
@@ -468,12 +444,8 @@ void EditorManager::setCurrentEditor(IEditor *editor, bool ignoreNavigationHisto
|
||||
qDebug() << Q_FUNC_INFO << (addToHistory ? "adding to history" : "not adding to history");
|
||||
if (addToHistory)
|
||||
addCurrentPositionToNavigationHistory(true);
|
||||
EditorGroup *group = groupOfEditor(editor);
|
||||
if (!group)
|
||||
return;
|
||||
m_d->m_suppressEditorChanges = true;
|
||||
m_d->m_splitter->setCurrentGroup(group);
|
||||
group->setCurrentEditor(editor);
|
||||
m_d->m_view->setCurrentEditor(editor);
|
||||
m_d->m_suppressEditorChanges = false;
|
||||
if (addToHistory)
|
||||
addCurrentPositionToNavigationHistory();
|
||||
@@ -486,15 +458,6 @@ void EditorManager::editorChanged(IEditor *toEditor)
|
||||
emit currentEditorChanged(toEditor);
|
||||
}
|
||||
|
||||
EditorGroup *EditorManager::groupOfEditor(IEditor *editor) const
|
||||
{
|
||||
foreach (EditorGroup *group, m_d->m_splitter->groups()) {
|
||||
if (group->editors().contains(editor))
|
||||
return group;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QList<IEditor *> EditorManager::editorsForFileName(const QString &filename) const
|
||||
{
|
||||
QList<IEditor *> found;
|
||||
@@ -508,23 +471,9 @@ QList<IEditor *> EditorManager::editorsForFileName(const QString &filename) cons
|
||||
|
||||
IEditor *EditorManager::currentEditor() const
|
||||
{
|
||||
return m_d->m_splitter->currentGroup()->currentEditor();
|
||||
return m_d->m_view->currentEditor();
|
||||
}
|
||||
|
||||
EditorGroup *EditorManager::currentEditorGroup() const
|
||||
{
|
||||
return m_d->m_splitter->currentGroup();
|
||||
}
|
||||
|
||||
void EditorManager::duplicateEditor()
|
||||
{
|
||||
IEditor *curEditor = currentEditor();
|
||||
if (!curEditor || !curEditor->duplicateSupported())
|
||||
return;
|
||||
IEditor *editor = curEditor->duplicate(this);
|
||||
registerDuplicate(curEditor, editor);
|
||||
insertEditor(editor);
|
||||
}
|
||||
|
||||
// SLOT connected to action
|
||||
// since this is potentially called in the event handler of the editor
|
||||
@@ -559,13 +508,7 @@ QList<IEditor*>
|
||||
foreach (IFile *file, files) {
|
||||
foreach (IEditor *editor, editors) {
|
||||
if (editor->file() == file && !found.contains(editor)) {
|
||||
if (hasDuplicate(editor)) {
|
||||
foreach (IEditor *duplicate, duplicates(editor)) {
|
||||
found << duplicate;
|
||||
}
|
||||
} else {
|
||||
found << editor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -580,13 +523,7 @@ QList<IFile *>
|
||||
foreach (IEditor *editor, editors) {
|
||||
if (!handledEditors.contains(editor)) {
|
||||
files << editor->file();
|
||||
if (hasDuplicate(editor)) {
|
||||
foreach (IEditor *duplicate, duplicates(editor)) {
|
||||
handledEditors << duplicate;
|
||||
}
|
||||
} else {
|
||||
handledEditors.insert(editor);
|
||||
}
|
||||
handledEditors.insert(editor);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
@@ -654,14 +591,10 @@ bool EditorManager::closeEditors(const QList<IEditor*> editorsToClose, bool askA
|
||||
m_d->m_editorStates.insert(editor->file()->fileName(), QVariant(state));
|
||||
}
|
||||
unregisterEditor(editor);
|
||||
if (hasDuplicate(editor))
|
||||
unregisterDuplicate(editor);
|
||||
m_d->m_core->removeContextObject(editor);
|
||||
EditorGroup *group = groupOfEditor(editor);
|
||||
const bool suppress = m_d->m_suppressEditorChanges;
|
||||
m_d->m_suppressEditorChanges = true;
|
||||
if (group)
|
||||
group->removeEditor(editor);
|
||||
m_d->m_view->removeEditor(editor);
|
||||
m_d->m_suppressEditorChanges = suppress;
|
||||
}
|
||||
emit editorsClosed(acceptedEditors);
|
||||
@@ -772,18 +705,13 @@ IEditor *EditorManager::createEditor(const QString &editorKind,
|
||||
}
|
||||
|
||||
void EditorManager::insertEditor(IEditor *editor,
|
||||
bool ignoreNavigationHistory,
|
||||
EditorGroup *group)
|
||||
bool ignoreNavigationHistory)
|
||||
{
|
||||
if (!editor)
|
||||
return;
|
||||
m_d->m_core->addContextObject(editor);
|
||||
registerEditor(editor);
|
||||
if (group)
|
||||
group->addEditor(editor);
|
||||
else
|
||||
m_d->m_splitter->currentGroup()->addEditor(editor);
|
||||
|
||||
m_d->m_view->addEditor(editor);
|
||||
setCurrentEditor(editor, ignoreNavigationHistory);
|
||||
emit editorOpened(editor);
|
||||
}
|
||||
@@ -1160,7 +1088,7 @@ void EditorManager::updateActions()
|
||||
m_d->m_revertToSavedAction->setText(tr("Revert %1 to Saved").arg(fName));
|
||||
|
||||
|
||||
m_d->m_closeCurrentEditorAction->setEnabled(m_d->m_splitter->currentGroup()->editorCount() > 0);
|
||||
m_d->m_closeCurrentEditorAction->setEnabled(curEditor != 0);
|
||||
m_d->m_closeCurrentEditorAction->setText(tr("Close %1").arg(fName));
|
||||
m_d->m_closeAllEditorsAction->setEnabled(openedCount > 0);
|
||||
|
||||
@@ -1169,20 +1097,17 @@ void EditorManager::updateActions()
|
||||
m_d->m_goBackAction->setEnabled(m_d->currentNavigationHistoryPosition > 0);
|
||||
m_d->m_goForwardAction->setEnabled(m_d->currentNavigationHistoryPosition < m_d->m_navigationHistory.size()-1);
|
||||
|
||||
m_d->m_duplicateAction->setEnabled(curEditor != 0 && curEditor->duplicateSupported());
|
||||
|
||||
m_d->m_openInExternalEditorAction->setEnabled(curEditor != 0);
|
||||
}
|
||||
|
||||
QList<IEditor*> EditorManager::openedEditors() const
|
||||
{
|
||||
return m_d->m_editorModel->editors();
|
||||
QList<IEditor*> editors;
|
||||
const QList<EditorGroup*> groups = m_d->m_splitter->groups();
|
||||
foreach (EditorGroup *group, groups) {
|
||||
editors += group->editors();
|
||||
}
|
||||
return editors;
|
||||
return m_d->m_view->editors();
|
||||
}
|
||||
|
||||
QList<IEditor*> EditorManager::openedEditorsNoDuplicates() const
|
||||
{
|
||||
return m_d->m_view->editors();
|
||||
}
|
||||
|
||||
Internal::EditorModel *EditorManager::openedEditorsModel() const
|
||||
@@ -1191,11 +1116,6 @@ Internal::EditorModel *EditorManager::openedEditorsModel() const
|
||||
}
|
||||
|
||||
|
||||
QList<EditorGroup *> EditorManager::editorGroups() const
|
||||
{
|
||||
return m_d->m_splitter->groups();
|
||||
}
|
||||
|
||||
QList<IEditor*> EditorManager::editorHistory() const
|
||||
{
|
||||
return m_d->m_editorHistory;
|
||||
@@ -1299,79 +1219,49 @@ void EditorManager::showWindowPopup() const
|
||||
m_d->m_windowPopup->setVisible(true);
|
||||
}
|
||||
|
||||
void EditorManager::registerDuplicate(IEditor *original,
|
||||
IEditor *duplicate)
|
||||
{
|
||||
QList<IEditor *> *duplicateList;
|
||||
if (m_d->m_duplicates.contains(original)) {
|
||||
duplicateList = m_d->m_duplicates.value(original);
|
||||
} else {
|
||||
duplicateList = new QList<IEditor *>;
|
||||
duplicateList->append(original);
|
||||
m_d->m_duplicates.insert(original, duplicateList);
|
||||
}
|
||||
duplicateList->append(duplicate);
|
||||
m_d->m_duplicates.insert(duplicate, duplicateList);
|
||||
}
|
||||
|
||||
void EditorManager::unregisterDuplicate(IEditor *editor)
|
||||
{
|
||||
if (!m_d->m_duplicates.contains(editor))
|
||||
return;
|
||||
QList<IEditor *> *duplicateList = m_d->m_duplicates.value(editor);
|
||||
duplicateList->removeAll(editor);
|
||||
m_d->m_duplicates.remove(editor);
|
||||
if (duplicateList->count() < 2) {
|
||||
foreach (IEditor *other, *duplicateList) {
|
||||
m_d->m_duplicates.remove(other);
|
||||
}
|
||||
delete duplicateList;
|
||||
}
|
||||
}
|
||||
|
||||
bool EditorManager::hasDuplicate(IEditor *editor) const
|
||||
{
|
||||
return m_d->m_duplicates.contains(editor);
|
||||
}
|
||||
|
||||
QList<IEditor *>
|
||||
EditorManager::duplicates(IEditor *editor) const
|
||||
{
|
||||
if (m_d->m_duplicates.contains(editor))
|
||||
return *m_d->m_duplicates.value(editor);
|
||||
return QList<IEditor *>() << editor;
|
||||
}
|
||||
|
||||
QByteArray EditorManager::saveState() const
|
||||
{
|
||||
//todo: versioning
|
||||
QByteArray bytes;
|
||||
QDataStream stream(&bytes, QIODevice::WriteOnly);
|
||||
stream << m_d->m_splitter->saveState();
|
||||
stream << saveOpenEditorList();
|
||||
|
||||
qDebug() << "saveState";
|
||||
stream << QByteArray("EditorManagerV1");
|
||||
|
||||
stream << m_d->m_editorStates;
|
||||
|
||||
QList<IEditor *> editors = openedEditorsNoDuplicates();
|
||||
int editorCount = editors.count();
|
||||
|
||||
qDebug() << "save editors:" << editorCount;
|
||||
|
||||
stream << editorCount;
|
||||
foreach (IEditor *editor, editors) {
|
||||
stream << editor->file()->fileName() << QByteArray(editor->kind());
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
bool EditorManager::restoreState(const QByteArray &state)
|
||||
{
|
||||
closeAllEditors(true);
|
||||
//todo: versioning
|
||||
QDataStream stream(state);
|
||||
QByteArray data;
|
||||
QMap<QString, QVariant> editorstates;
|
||||
stream >> data;
|
||||
const bool success = m_d->m_splitter->restoreState(data);
|
||||
if (!success)
|
||||
|
||||
QByteArray version;
|
||||
stream >> version;
|
||||
|
||||
qDebug() << "restore state" << version;
|
||||
|
||||
if (version != "EditorManagerV1")
|
||||
return false;
|
||||
|
||||
QMap<QString, QVariant> editorstates;
|
||||
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
bool editorChangesSuppressed = m_d->m_suppressEditorChanges;
|
||||
m_d->m_suppressEditorChanges = true;
|
||||
|
||||
stream >> data;
|
||||
restoreOpenEditorList(data);
|
||||
stream >> editorstates;
|
||||
QMapIterator<QString, QVariant> i(editorstates);
|
||||
while (i.hasNext()) {
|
||||
@@ -1379,6 +1269,18 @@ bool EditorManager::restoreState(const QByteArray &state)
|
||||
m_d->m_editorStates.insert(i.key(), i.value());
|
||||
}
|
||||
|
||||
int editorCount = 0;
|
||||
stream >> editorCount;
|
||||
qDebug() << "restore editors:" << editorCount;
|
||||
while (--editorCount >= 0) {
|
||||
QString fileName;
|
||||
stream >> fileName;
|
||||
QByteArray kind;
|
||||
stream >> kind;
|
||||
qDebug() << "openEditor" << fileName << kind;
|
||||
openEditor(fileName, kind, true);
|
||||
}
|
||||
|
||||
m_d->m_suppressEditorChanges = editorChangesSuppressed;
|
||||
if (currentEditor())
|
||||
setCurrentEditor(currentEditor());// looks like a null-op but is not
|
||||
@@ -1390,7 +1292,6 @@ bool EditorManager::restoreState(const QByteArray &state)
|
||||
|
||||
void EditorManager::saveSettings(QSettings *settings)
|
||||
{
|
||||
m_d->m_splitter->saveSettings(settings);
|
||||
settings->setValue(QLatin1String("EditorManager/DocumentStates"),
|
||||
m_d->m_editorStates);
|
||||
settings->setValue(QLatin1String("EditorManager/ExternalEditorCommand"),
|
||||
@@ -1399,7 +1300,6 @@ void EditorManager::saveSettings(QSettings *settings)
|
||||
|
||||
void EditorManager::readSettings(QSettings *settings)
|
||||
{
|
||||
m_d->m_splitter->readSettings(settings);
|
||||
if (settings->contains(QLatin1String("EditorManager/DocumentStates")))
|
||||
m_d->m_editorStates = settings->value(QLatin1String("EditorManager/DocumentStates"))
|
||||
.value<QMap<QString, QVariant> >();
|
||||
@@ -1407,56 +1307,6 @@ void EditorManager::readSettings(QSettings *settings)
|
||||
m_d->m_externalEditor = settings->value(QLatin1String("EditorManager/ExternalEditorCommand")).toString();
|
||||
}
|
||||
|
||||
QByteArray EditorManager::saveOpenEditorList() const
|
||||
{
|
||||
QByteArray bytes;
|
||||
QDataStream stream(&bytes, QIODevice::WriteOnly);
|
||||
QMap<QString, QByteArray> outlist;
|
||||
QMapIterator<QString, EditorGroup *> i(m_d->m_splitter->pathGroupMap());
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
outlist.insert(i.key(), i.value()->saveState());
|
||||
}
|
||||
stream << outlist;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void EditorManager::restoreOpenEditorList(const QByteArray &state)
|
||||
{
|
||||
QDataStream in(state);
|
||||
QMap<QString, EditorGroup *> pathGroupMap = m_d->m_splitter->pathGroupMap();
|
||||
QMap<QString, QByteArray> inlist;
|
||||
in >> inlist;
|
||||
QMapIterator<QString, QByteArray> i(inlist);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
EditorGroup *group = pathGroupMap.value(i.key());
|
||||
if (!group)
|
||||
continue;
|
||||
group->restoreState(i.value());
|
||||
}
|
||||
}
|
||||
|
||||
IEditor *EditorManager::restoreEditor(QString fileName, QString editorKind, EditorGroup *group)
|
||||
{
|
||||
IEditor *editor;
|
||||
QList<IEditor *> existing =
|
||||
editorsForFileName(fileName);
|
||||
if (!existing.isEmpty()) {
|
||||
IEditor *first = existing.first();
|
||||
if (!first->duplicateSupported())
|
||||
return 0;
|
||||
editor = first->duplicate(this);
|
||||
registerDuplicate(first, editor);
|
||||
} else {
|
||||
editor = createEditor(editorKind, fileName);
|
||||
if (!editor || !editor->open(fileName))
|
||||
return 0;
|
||||
}
|
||||
insertEditor(editor, false, group);
|
||||
restoreEditorState(editor);
|
||||
return editor;
|
||||
}
|
||||
|
||||
void EditorManager::revertToSaved()
|
||||
{
|
||||
@@ -1488,13 +1338,13 @@ void EditorManager::showEditorInfoBar(const QString &kind,
|
||||
const QString &buttonText,
|
||||
QObject *object, const char *member)
|
||||
{
|
||||
m_d->m_splitter->currentGroup()->showEditorInfoBar(kind, infoText, buttonText, object, member);
|
||||
m_d->m_view->showEditorInfoBar(kind, infoText, buttonText, object, member);
|
||||
}
|
||||
|
||||
|
||||
void EditorManager::hideEditorInfoBar(const QString &kind)
|
||||
{
|
||||
m_d->m_splitter->currentGroup()->hideEditorInfoBar(kind);
|
||||
m_d->m_view->hideEditorInfoBar(kind);
|
||||
}
|
||||
|
||||
QString EditorManager::externalEditorHelpText() const
|
||||
|
||||
@@ -69,7 +69,7 @@ struct EditorManagerPrivate;
|
||||
namespace Internal {
|
||||
class OpenEditorsWindow;
|
||||
class EditorModel;
|
||||
class EditorSplitter;
|
||||
//class EditorSplitter;
|
||||
|
||||
class EditorClosingCoreListener;
|
||||
class OpenEditorsViewFactory;
|
||||
@@ -118,19 +118,18 @@ public:
|
||||
|
||||
void setCurrentEditor(IEditor *editor, bool ignoreNavigationHistory = false);
|
||||
IEditor *currentEditor() const;
|
||||
EditorGroup *currentEditorGroup() const;
|
||||
// EditorGroup *currentEditorGroup() const;
|
||||
|
||||
QList<IEditor*> openedEditors() const;
|
||||
QList<IEditor*> openedEditorsNoDuplicates() const;
|
||||
|
||||
Internal::EditorModel *openedEditorsModel() const;
|
||||
|
||||
QList<IEditor*> editorsForFiles(QList<IFile*> files) const;
|
||||
QList<EditorGroup *> editorGroups() const;
|
||||
//QList<EditorGroup *> editorGroups() const;
|
||||
QList<IEditor*> editorHistory() const;
|
||||
void addCurrentPositionToNavigationHistory(bool compress = false);
|
||||
|
||||
bool hasDuplicate(IEditor *editor) const;
|
||||
|
||||
bool saveEditor(IEditor *editor);
|
||||
|
||||
bool closeEditors(const QList<IEditor *> editorsToClose, bool askAboutModifiedEditors = true);
|
||||
@@ -150,7 +149,7 @@ public:
|
||||
Internal::OpenEditorsWindow *windowPopup() const;
|
||||
void showWindowPopup() const;
|
||||
|
||||
Internal::EditorSplitter *editorSplitter() const;
|
||||
// Internal::EditorSplitter *editorSplitter() const;
|
||||
|
||||
void showEditorInfoBar(const QString &kind,
|
||||
const QString &infoText,
|
||||
@@ -198,7 +197,6 @@ private slots:
|
||||
void updateCurrentEditorAndGroup(Core::IContext *context);
|
||||
void updateEditorHistory();
|
||||
void updateActions();
|
||||
void duplicateEditor();
|
||||
void revertToSaved();
|
||||
void goBackInNavigationHistory();
|
||||
void goForwardInNavigationHistory();
|
||||
@@ -208,18 +206,11 @@ private:
|
||||
QList<IFile *> filesForEditors(QList<IEditor *> editors) const;
|
||||
IEditor *createEditor(const QString &mimeType = QString(),
|
||||
const QString &fileName = QString());
|
||||
void insertEditor(IEditor *editor, bool ignoreNavigationHistory = false, EditorGroup *group = 0);
|
||||
void insertEditor(IEditor *editor, bool ignoreNavigationHistory = false);
|
||||
bool registerEditor(IEditor *editor);
|
||||
bool unregisterEditor(IEditor *editor);
|
||||
EditorGroup *groupOfEditor(IEditor *editor) const;
|
||||
void editorChanged(IEditor *editor);
|
||||
void registerDuplicate(IEditor *original,
|
||||
IEditor *duplicate);
|
||||
void unregisterDuplicate(IEditor *editor);
|
||||
QList<IEditor *> duplicates(IEditor *editor) const;
|
||||
|
||||
QByteArray saveOpenEditorList() const;
|
||||
void restoreOpenEditorList(const QByteArray &state);
|
||||
void restoreEditorState(IEditor *editor);
|
||||
|
||||
static EditorManager *m_instance;
|
||||
|
||||
469
src/plugins/coreplugin/editormanager/editorview.cpp
Normal file
469
src/plugins/coreplugin/editormanager/editorview.cpp
Normal file
@@ -0,0 +1,469 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
**
|
||||
** Non-Open Source Usage
|
||||
**
|
||||
** Licensees may use this file in accordance with the Qt Beta Version
|
||||
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||
** alternatively, in accordance with the terms contained in a written
|
||||
** agreement between you and Nokia.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||
** of this file. Please review the following information to ensure GNU
|
||||
** General Public Licensing requirements will be met:
|
||||
**
|
||||
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "editorview.h"
|
||||
#include "editormanager.h"
|
||||
#include "coreimpl.h"
|
||||
|
||||
#include <utils/qtcassert.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/QToolBar>
|
||||
#include <QtGui/QToolButton>
|
||||
#ifdef Q_WS_MAC
|
||||
#include <qmacstyle_mac.h>
|
||||
#endif
|
||||
|
||||
Q_DECLARE_METATYPE(Core::IEditor *)
|
||||
|
||||
using namespace Core;
|
||||
using namespace Core::Internal;
|
||||
|
||||
|
||||
//================EditorModel====================
|
||||
int EditorModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EditorModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
return m_editors.count();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EditorModel::addEditor(IEditor *editor)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
QString fileName = editor->file()->fileName();
|
||||
for (index = 0; index < m_editors.count(); ++index)
|
||||
if (fileName < m_editors.at(index)->file()->fileName())
|
||||
break;
|
||||
|
||||
beginInsertRows(QModelIndex(), index, index);
|
||||
m_editors.insert(index, editor);
|
||||
connect(editor, SIGNAL(changed()), this, SLOT(itemChanged()));
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void EditorModel::removeEditor(IEditor *editor)
|
||||
{
|
||||
int idx = m_editors.indexOf(editor);
|
||||
if (idx < 0)
|
||||
return;
|
||||
beginRemoveRows(QModelIndex(), idx, idx);
|
||||
m_editors.removeAt(idx);
|
||||
endRemoveRows();
|
||||
disconnect(editor, SIGNAL(changed()), this, SLOT(itemChanged()));
|
||||
}
|
||||
|
||||
|
||||
void EditorModel::emitDataChanged(IEditor *editor)
|
||||
{
|
||||
int idx = m_editors.indexOf(editor);
|
||||
if (idx < 0)
|
||||
return;
|
||||
QModelIndex mindex = index(idx, 0);
|
||||
emit dataChanged(mindex, mindex);
|
||||
}
|
||||
|
||||
QModelIndex EditorModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
if (column != 0 || row < 0 || row >= m_editors.count())
|
||||
return QModelIndex();
|
||||
return createIndex(row, column);
|
||||
}
|
||||
|
||||
QVariant EditorModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
IEditor *editor = m_editors.at(index.row());
|
||||
QTC_ASSERT(editor, return QVariant());
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
return editor->file()->isModified()
|
||||
? editor->displayName() + QLatin1String("*")
|
||||
: editor->displayName();
|
||||
case Qt::DecorationRole:
|
||||
return editor->file()->isReadOnly()
|
||||
? QIcon(QLatin1String(":/core/images/locked.png"))
|
||||
: QIcon();
|
||||
case Qt::ToolTipRole:
|
||||
return editor->file()->fileName().isEmpty()
|
||||
? editor->displayName()
|
||||
: QDir::toNativeSeparators(editor->file()->fileName());
|
||||
case Qt::UserRole:
|
||||
return qVariantFromValue(editor);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex EditorModel::indexOf(IEditor *editor) const
|
||||
{
|
||||
int idx = m_editors.indexOf(editor);
|
||||
if (idx < 0)
|
||||
return indexOf(editor->file()->fileName());
|
||||
return createIndex(idx, 0);
|
||||
}
|
||||
|
||||
QModelIndex EditorModel::indexOf(const QString &fileName) const
|
||||
{
|
||||
for (int i = 0; i < m_editors.count(); ++i)
|
||||
if (m_editors.at(i)->file()->fileName() == fileName)
|
||||
return createIndex(i, 0);
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
|
||||
void EditorModel::itemChanged()
|
||||
{
|
||||
emitDataChanged(qobject_cast<IEditor*>(sender()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================EditorView====================
|
||||
|
||||
EditorView::EditorView(EditorModel *model, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
m_toplevel(new QWidget),
|
||||
m_toolBar(new QWidget),
|
||||
m_container(new QStackedWidget(this)),
|
||||
m_editorList(new QComboBox),
|
||||
m_closeButton(new QToolButton),
|
||||
m_lockButton(new QToolButton),
|
||||
m_defaultToolBar(new QToolBar(this)),
|
||||
m_infoWidget(new QFrame(this)),
|
||||
m_editorForInfoWidget(0)
|
||||
{
|
||||
QVBoxLayout *tl = new QVBoxLayout(m_toplevel);
|
||||
tl->setSpacing(0);
|
||||
tl->setMargin(0);
|
||||
{
|
||||
m_editorList->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
m_editorList->setMinimumContentsLength(20);
|
||||
m_editorList->setModel(model);
|
||||
m_editorList->setMaxVisibleItems(40);
|
||||
|
||||
QToolBar *editorListToolBar = new QToolBar;
|
||||
|
||||
editorListToolBar->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
|
||||
editorListToolBar->addWidget(m_editorList);
|
||||
|
||||
m_defaultToolBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
m_activeToolBar = m_defaultToolBar;
|
||||
|
||||
QHBoxLayout *toolBarLayout = new QHBoxLayout;
|
||||
toolBarLayout->setMargin(0);
|
||||
toolBarLayout->setSpacing(0);
|
||||
toolBarLayout->addWidget(m_defaultToolBar);
|
||||
m_toolBar->setLayout(toolBarLayout);
|
||||
|
||||
m_lockButton->setAutoRaise(true);
|
||||
m_lockButton->setProperty("type", QLatin1String("dockbutton"));
|
||||
|
||||
m_closeButton->setAutoRaise(true);
|
||||
m_closeButton->setIcon(QIcon(":/core/images/closebutton.png"));
|
||||
m_closeButton->setProperty("type", QLatin1String("dockbutton"));
|
||||
|
||||
QToolBar *rightToolBar = new QToolBar;
|
||||
rightToolBar->setLayoutDirection(Qt::RightToLeft);
|
||||
rightToolBar->addWidget(m_closeButton);
|
||||
rightToolBar->addWidget(m_lockButton);
|
||||
|
||||
QHBoxLayout *toplayout = new QHBoxLayout;
|
||||
toplayout->setSpacing(0);
|
||||
toplayout->setMargin(0);
|
||||
toplayout->addWidget(editorListToolBar);
|
||||
toplayout->addWidget(m_toolBar, 1); // Custom toolbar stretches
|
||||
toplayout->addWidget(rightToolBar);
|
||||
|
||||
QWidget *top = new QWidget;
|
||||
QVBoxLayout *vlayout = new QVBoxLayout(top);
|
||||
vlayout->setSpacing(0);
|
||||
vlayout->setMargin(0);
|
||||
vlayout->addLayout(toplayout);
|
||||
tl->addWidget(top);
|
||||
|
||||
connect(m_editorList, SIGNAL(currentIndexChanged(int)), this, SLOT(listSelectionChanged(int)));
|
||||
connect(m_lockButton, SIGNAL(clicked()), this, SLOT(makeEditorWritable()));
|
||||
connect(m_closeButton, SIGNAL(clicked()), this, SLOT(sendCloseRequest()));
|
||||
}
|
||||
{
|
||||
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);
|
||||
|
||||
QHBoxLayout *l = new QHBoxLayout;
|
||||
l->setSpacing(0);
|
||||
l->setMargin(0);
|
||||
l->addWidget(m_toplevel);
|
||||
setLayout(l);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
EditorView::~EditorView()
|
||||
{
|
||||
}
|
||||
|
||||
void EditorView::focusInEvent(QFocusEvent *e)
|
||||
{
|
||||
if (m_container->count() > 0) {
|
||||
setEditorFocus(m_container->currentIndex());
|
||||
} else {
|
||||
QWidget::focusInEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorView::setEditorFocus(int index)
|
||||
{
|
||||
QWidget *w = m_container->widget(index);
|
||||
w->setFocus();
|
||||
}
|
||||
|
||||
void EditorView::addEditor(IEditor *editor)
|
||||
{
|
||||
insertEditor(editorCount(), editor);
|
||||
}
|
||||
|
||||
void EditorView::insertEditor(int index, IEditor *editor)
|
||||
{
|
||||
if (m_container->indexOf(editor->widget()) != -1)
|
||||
return;
|
||||
|
||||
m_container->insertWidget(index, editor->widget());
|
||||
m_widgetEditorMap.insert(editor->widget(), editor);
|
||||
|
||||
QToolBar *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()));
|
||||
|
||||
// emit editorAdded(editor);
|
||||
}
|
||||
|
||||
void EditorView::sendCloseRequest()
|
||||
{
|
||||
emit closeRequested(currentEditor());
|
||||
}
|
||||
|
||||
void EditorView::removeEditor(IEditor *editor)
|
||||
{
|
||||
QTC_ASSERT(editor, return);
|
||||
const int index = m_container->indexOf(editor->widget());
|
||||
if (index != -1) {
|
||||
m_container->removeWidget(editor->widget());
|
||||
m_widgetEditorMap.remove(editor->widget());
|
||||
editor->widget()->setParent(0);
|
||||
disconnect(editor, SIGNAL(changed()), this, SLOT(updateEditorStatus()));
|
||||
QToolBar *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);
|
||||
}
|
||||
// emit editorRemoved(editor);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
return;
|
||||
const int idx = m_container->indexOf(editor->widget());
|
||||
QTC_ASSERT(idx >= 0, return);
|
||||
if (m_container->currentIndex() != idx) {
|
||||
m_container->setCurrentIndex(idx);
|
||||
|
||||
const bool block = m_editorList->blockSignals(true);
|
||||
m_editorList->setCurrentIndex(qobject_cast<EditorModel*>(m_editorList->model())->indexOf(editor->file()->fileName()).row());
|
||||
m_editorList->blockSignals(block);
|
||||
}
|
||||
setEditorFocus(idx);
|
||||
|
||||
updateEditorStatus(editor);
|
||||
updateToolBar(editor);
|
||||
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"));
|
||||
|
||||
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)
|
||||
{
|
||||
QToolBar *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::listSelectionChanged(int index)
|
||||
{
|
||||
QAbstractItemModel *model = m_editorList->model();
|
||||
setCurrentEditor(model->data(model->index(index, 0), Qt::UserRole).value<IEditor*>());
|
||||
}
|
||||
|
||||
|
||||
151
src/plugins/coreplugin/editormanager/editorview.h
Normal file
151
src/plugins/coreplugin/editormanager/editorview.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/***************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||
**
|
||||
**
|
||||
** Non-Open Source Usage
|
||||
**
|
||||
** Licensees may use this file in accordance with the Qt Beta Version
|
||||
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||
** alternatively, in accordance with the terms contained in a written
|
||||
** agreement between you and Nokia.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||
** of this file. Please review the following information to ensure GNU
|
||||
** General Public Licensing requirements will be met:
|
||||
**
|
||||
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#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 <coreplugin/icontext.h>
|
||||
|
||||
#include <QtCore/QMap>
|
||||
#include <QtGui/QSortFilterProxyModel>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QComboBox;
|
||||
class QToolBar;
|
||||
class QToolButton;
|
||||
class QLabel;
|
||||
class QStackedWidget;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Core {
|
||||
|
||||
class IEditor;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class EditorModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
EditorModel(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);
|
||||
|
||||
void removeEditor(IEditor *editor);
|
||||
void emitDataChanged(IEditor *editor);
|
||||
|
||||
QList<IEditor *> editors() const { return m_editors; }
|
||||
QModelIndex indexOf(IEditor *editor) const;
|
||||
QModelIndex indexOf(const QString &filename) const;
|
||||
|
||||
private slots:
|
||||
void itemChanged();
|
||||
private:
|
||||
QList<IEditor *> m_editors;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class EditorView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EditorView(EditorModel *model = 0, QWidget *parent = 0);
|
||||
virtual ~EditorView();
|
||||
|
||||
//EditorGroup
|
||||
int editorCount() const;
|
||||
void addEditor(IEditor *editor);
|
||||
void insertEditor(int i, IEditor *editor);
|
||||
void removeEditor(IEditor *editor);
|
||||
IEditor *currentEditor() const;
|
||||
void setCurrentEditor(IEditor *editor);
|
||||
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 focusInEvent(QFocusEvent *e);
|
||||
|
||||
signals:
|
||||
void closeRequested(Core::IEditor *editor);
|
||||
|
||||
private slots:
|
||||
void sendCloseRequest();
|
||||
void updateEditorStatus(Core::IEditor *editor = 0);
|
||||
void checkEditorStatus();
|
||||
void setEditorFocus(int index);
|
||||
void makeEditorWritable();
|
||||
void listSelectionChanged(int index);
|
||||
|
||||
private:
|
||||
void updateToolBar(IEditor *editor);
|
||||
void checkProjectLoaded(IEditor *editor);
|
||||
|
||||
QWidget *m_toplevel;
|
||||
QWidget *m_toolBar;
|
||||
QToolBar *m_activeToolBar;
|
||||
QStackedWidget *m_container;
|
||||
QComboBox *m_editorList;
|
||||
QToolButton *m_closeButton;
|
||||
QToolButton *m_lockButton;
|
||||
QToolBar *m_defaultToolBar;
|
||||
QString m_infoWidgetKind;
|
||||
QFrame *m_infoWidget;
|
||||
QLabel *m_infoWidgetLabel;
|
||||
QToolButton *m_infoWidgetButton;
|
||||
IEditor *m_editorForInfoWidget;
|
||||
QSortFilterProxyModel m_proxyModel;
|
||||
QMap<QWidget *, IEditor *> m_widgetEditorMap;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif // EDITORVIEW_H
|
||||
@@ -32,8 +32,8 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "openeditorsview.h"
|
||||
#include "editorgroup.h"
|
||||
#include "editormanager.h"
|
||||
#include "editorview.h"
|
||||
#include "coreimpl.h"
|
||||
|
||||
#include <coreplugin/coreconstants.h>
|
||||
|
||||
@@ -46,6 +46,15 @@ const int OpenEditorsWindow::WIDTH = 300;
|
||||
const int OpenEditorsWindow::HEIGHT = 200;
|
||||
const int OpenEditorsWindow::MARGIN = 4;
|
||||
|
||||
bool OpenEditorsWindow::isSameFile(IEditor *editorA, IEditor *editorB) const
|
||||
{
|
||||
if (editorA == editorB)
|
||||
return true;
|
||||
if (!editorA || !editorB)
|
||||
return false;
|
||||
return editorA->file()->fileName() == editorB->file()->fileName();
|
||||
}
|
||||
|
||||
OpenEditorsWindow::OpenEditorsWindow(QWidget *parent) :
|
||||
QWidget(parent, Qt::Popup),
|
||||
m_editorList(new QTreeWidget(this)),
|
||||
@@ -216,14 +225,14 @@ void OpenEditorsWindow::updateHistory()
|
||||
for (int i = 0; i < common; ++i) {
|
||||
item = m_editorList->topLevelItem(i);
|
||||
updateItem(item, history.at(i));
|
||||
if (history.at(i) == m_current)
|
||||
if (isSameFile(history.at(i), m_current))
|
||||
selectedIndex = i;
|
||||
}
|
||||
for (int i = common; i < num; ++i) {
|
||||
item = new QTreeWidgetItem(QStringList() << "");
|
||||
updateItem(item, history.at(i));
|
||||
m_editorList->addTopLevelItem(item);
|
||||
if (history.at(i) == m_current)
|
||||
if (isSameFile(history.at(i), m_current))
|
||||
selectedIndex = i;
|
||||
}
|
||||
for (int i = oldNum-1; i >= common; --i) {
|
||||
@@ -237,38 +246,23 @@ void OpenEditorsWindow::updateHistory()
|
||||
void OpenEditorsWindow::updateList()
|
||||
{
|
||||
EditorManager *em = EditorManager::instance();
|
||||
QList<EditorGroup *> groups = em->editorGroups();
|
||||
int oldNum = m_editorList->topLevelItemCount();
|
||||
int curItem = 0;
|
||||
int selectedIndex = -1;
|
||||
QTreeWidgetItem *item;
|
||||
for (int i = 0; i < groups.count(); ++i) {
|
||||
if (groups.count() > 1) {
|
||||
if (curItem < oldNum) {
|
||||
item = m_editorList->topLevelItem(curItem);
|
||||
} else {
|
||||
item = new QTreeWidgetItem(QStringList()<<"");
|
||||
m_editorList->addTopLevelItem(item);
|
||||
}
|
||||
curItem++;
|
||||
item->setText(0, tr("---Group %1---").arg(i));
|
||||
item->setFlags(0);
|
||||
item->setData(0, Qt::UserRole, QVariant());
|
||||
foreach (IEditor *editor, em->openedEditorsNoDuplicates()){
|
||||
if (curItem < oldNum) {
|
||||
item = m_editorList->topLevelItem(curItem);
|
||||
} else {
|
||||
item = new QTreeWidgetItem(QStringList()<<"");
|
||||
m_editorList->addTopLevelItem(item);
|
||||
}
|
||||
foreach (IEditor *editor, groups.at(i)->editors()) {
|
||||
if (curItem < oldNum) {
|
||||
item = m_editorList->topLevelItem(curItem);
|
||||
} else {
|
||||
item = new QTreeWidgetItem(QStringList()<<"");
|
||||
m_editorList->addTopLevelItem(item);
|
||||
}
|
||||
updateItem(item, editor);
|
||||
if (editor == m_current) {
|
||||
m_editorList->setCurrentItem(item);
|
||||
selectedIndex = curItem;
|
||||
}
|
||||
curItem++;
|
||||
updateItem(item, editor);
|
||||
if (isSameFile(editor, m_current)) {
|
||||
m_editorList->setCurrentItem(item);
|
||||
selectedIndex = curItem;
|
||||
}
|
||||
curItem++;
|
||||
}
|
||||
for (int i = oldNum-1; i >= curItem; --i) {
|
||||
delete m_editorList->takeTopLevelItem(i);
|
||||
@@ -338,7 +332,7 @@ void OpenEditorsWindow::updateSelectedEditor()
|
||||
for (int i = 0; i < num; ++i) {
|
||||
IEditor *editor = m_editorList->topLevelItem(i)
|
||||
->data(0, Qt::UserRole).value<IEditor *>();
|
||||
if (editor == m_current) {
|
||||
if (isSameFile(editor,m_current)) {
|
||||
m_editorList->setCurrentItem(m_editorList->topLevelItem(i));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -88,6 +88,8 @@ private:
|
||||
void centerOnItem(int selectedIndex);
|
||||
void selectUpDown(bool up);
|
||||
|
||||
bool isSameFile(IEditor *editorA, IEditor *editorB) const;
|
||||
|
||||
QTreeWidget *m_editorList;
|
||||
Mode m_mode;
|
||||
QTimer m_autoHide;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "stackededitorgroup.h"
|
||||
#include "editormanager.h"
|
||||
#include "editorview.h"
|
||||
#include "coreimpl.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
@@ -738,9 +738,9 @@ void MainWindow::setFocusToEditor()
|
||||
m_coreImpl->modeManager()->activateMode(QLatin1String(Constants::MODE_EDIT));
|
||||
}
|
||||
|
||||
EditorGroup *group = m_editorManager->currentEditorGroup();
|
||||
if (group && group->widget())
|
||||
group->widget()->setFocus();
|
||||
if (IEditor *editor = m_editorManager->currentEditor())
|
||||
editor->widget()->setFocus();
|
||||
|
||||
if (focusWidget && focusWidget == qApp->focusWidget()) {
|
||||
if (FindToolBarPlaceHolder::getCurrent())
|
||||
FindToolBarPlaceHolder::getCurrent()->hide();
|
||||
|
||||
@@ -345,9 +345,8 @@ void OutputPane::slotHide()
|
||||
int idx = m_widgetComboBox->itemData(m_widgetComboBox->currentIndex()).toInt();
|
||||
if (m_buttons.value(idx))
|
||||
m_buttons.value(idx)->setChecked(false);
|
||||
EditorGroup *group = Core::EditorManager::instance()->currentEditorGroup();
|
||||
if (group && group->widget())
|
||||
group->widget()->setFocus();
|
||||
if (IEditor *editor = Core::EditorManager::instance()->currentEditor())
|
||||
editor->widget()->setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -267,10 +267,10 @@ QList<Core::IEditor*> EditorManagerPrototype::editorHistory() const
|
||||
return callee()->editorHistory();
|
||||
}
|
||||
|
||||
QList<Core::EditorGroup *> EditorManagerPrototype::editorGroups() const
|
||||
{
|
||||
return callee()->editorGroups();
|
||||
}
|
||||
//QList<Core::EditorGroup *> EditorManagerPrototype::editorGroups() const
|
||||
//{
|
||||
// return callee()->editorGroups();
|
||||
//}
|
||||
|
||||
QList<Core::IEditor*> EditorManagerPrototype::editorsForFiles(QList<Core::IFile*> files) const
|
||||
{
|
||||
|
||||
@@ -170,7 +170,7 @@ class EditorManagerPrototype : public QObject, public QScriptable
|
||||
Q_PROPERTY(Core::IEditor* currentEditor READ currentEditor WRITE setCurrentEditor DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(QList<Core::IEditor*> openedEditors READ openedEditors DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(QList<Core::IEditor*> editorHistory READ editorHistory DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
Q_PROPERTY(QList<Core::EditorGroup *> editorGroups READ editorGroups DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
// Q_PROPERTY(QList<Core::EditorGroup *> editorGroups READ editorGroups DESIGNABLE false SCRIPTABLE true STORED false)
|
||||
public:
|
||||
typedef Core::EditorManager EditorManager;
|
||||
|
||||
@@ -180,7 +180,7 @@ public:
|
||||
void setCurrentEditor(Core::IEditor *editor);
|
||||
QList<Core::IEditor*> openedEditors() const;
|
||||
QList<Core::IEditor*> editorHistory() const;
|
||||
QList<Core::EditorGroup *> editorGroups() const;
|
||||
// QList<Core::EditorGroup *> editorGroups() const;
|
||||
|
||||
public slots:
|
||||
QList<Core::IEditor*> editorsForFiles(QList<Core::IFile*> files) const;
|
||||
|
||||
@@ -74,7 +74,7 @@ static inline QString msgServerFailure()
|
||||
inline Core::IEditor* locateEditor(const Core::ICore *core, const char *property, const QString &entry)
|
||||
{
|
||||
foreach (Core::IEditor *ed, core->editorManager()->openedEditors())
|
||||
if (ed->property(property).toString() == entry)
|
||||
if (ed->file()->property(property).toString() == entry)
|
||||
return ed;
|
||||
return 0;
|
||||
}
|
||||
@@ -173,7 +173,7 @@ VCSBase::VCSBaseEditor
|
||||
} else {
|
||||
// Create new, set wait message, set up with source and codec
|
||||
outputEditor = m_core->editorManager()->newFile(kind, &title, m_msgWait);
|
||||
outputEditor->setProperty(registerDynamicProperty, dynamicPropertyValue);
|
||||
outputEditor->file()->setProperty(registerDynamicProperty, dynamicPropertyValue);
|
||||
rc = VCSBase::VCSBaseEditor::getVcsBaseEditor(outputEditor);
|
||||
QTC_ASSERT(rc, return 0);
|
||||
rc->setSource(source);
|
||||
|
||||
@@ -895,7 +895,7 @@ void PerforcePlugin::p4Diff(const QStringList &files, QString diffname)
|
||||
}
|
||||
|
||||
foreach (Core::IEditor *ed, m_coreInstance->editorManager()->openedEditors()) {
|
||||
if (ed->property("originalFileName").toString() == fileName) {
|
||||
if (ed->file()->property("originalFileName").toString() == fileName) {
|
||||
existingEditor = ed;
|
||||
displayInEditor = false;
|
||||
break;
|
||||
@@ -913,7 +913,7 @@ void PerforcePlugin::p4Diff(const QStringList &files, QString diffname)
|
||||
|
||||
if (files.count() == 1) {
|
||||
if (displayInEditor && editor != 0) {
|
||||
editor->setProperty("originalFileName", files.at(0));
|
||||
editor->file()->setProperty("originalFileName", files.at(0));
|
||||
} else if (!displayInEditor && existingEditor) {
|
||||
if (existingEditor) {
|
||||
existingEditor->createNew(result.stdOut);
|
||||
|
||||
@@ -493,7 +493,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList & /*arguments*/, QStrin
|
||||
// build action
|
||||
m_buildAction = new QAction(tr("Build Project"), this);
|
||||
cmd = am->registerAction(m_buildAction, Constants::BUILD, globalcontext);
|
||||
cmd->setAttribute(Core::ICommand::CA_UpdateText);
|
||||
cmd->setAttribute(Core::Command::CA_UpdateText);
|
||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+B")));
|
||||
mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
|
||||
mproject->addAction(cmd, Constants::G_PROJECT_BUILD);
|
||||
|
||||
Reference in New Issue
Block a user