Merge branch '0.9.1-beta' of git@scm.dev.nokia.troll.no:creator/mainline into 0.9.1-beta

This commit is contained in:
dt
2008-12-05 14:30:48 +01:00
56 changed files with 1413 additions and 613 deletions

View File

@@ -814,21 +814,26 @@
a pointer to some private data structure, you will see a list of children, a pointer to some private data structure, you will see a list of children,
signals and slots. signals and slots.
Similarily, instead of showing a bunch of pointers and ints, Similarly, instead of displaying many pointers and integers, Qt Creator's
a QHash or QMap will display its contents in an orderly fashion, debugger will display the contents of a QHash or QMap in an orderly manner.
a QFileInfo will expose e.g. access data, and the otherwise Also, the debugger will display access data for QFileInfo and provide
"opaque" QVariant gives access to the "real" contents. access to the "real" contents of QVariant.
The \gui{Locals and Watchers View} can be used to change the
contents of variables of simple data types like int or float
while the program is stopped. To do so, click into the 'Value'
column, modify the value there, and hit \key{Return}.
The \gui{Locals and Watchers} view can be used to change the contents of
variables of simple data types such as \c int or \c float when the program
is stopped. To do so, click on the \gui Value column, modify the value
with the inplace editor, and hit \key Enter (or \key Return).
\section2 Modules \section2 Modules
The \gui{Modules View} is hidden by default and only useful in By default, the \gui Modules view is hidden as it is only useful with the
experimental delayed debug information loading feature. You can turn this
feature on by selecting \gui{Fast Debugger Start}
The \gui Modules view is hidden by default and only useful in
connection with the experimental feature of delayed debug connection with the experimental feature of delayed debug
information loading. This feature is accessible by selecting information loading. This feature is accessible by selecting
\gui{Debug} and \gui{Fast Debugger Start}. When using the \gui{Debug} and \gui{Fast Debugger Start}. When using the
@@ -849,29 +854,28 @@
commands commands
\section1 A Walkthrough for the Debugger Frontend
\section1 A short walk through the debugger frontend In our \l{Writing a Simple Program with Qt Creator}{TextFinder} example, we
read a text file into a QString and then display it with a QTextEdit.
In our \l{Writing a Simple Program with Qt Creator}{TextFinder} Suppose, you would like to look at this QString, \c{line}, and see what
example, we read a text file into a QString and then display it with a data it actually stores. Follow the steps described below to place a
QTextEdit. Suppose, you would like to look at this QString, \c{line}, breakpoint and view the QString object's data.
and see what data it actually stores. Follow the steps described below
to place a break point and view the QString object's data.
\table \table
\row \row
\i \inlineimage qtcreator-setting-breakpoint1.png \i \inlineimage qtcreator-setting-breakpoint1.png
\i \bold{Setting a Breakpoint} \i \bold{Setting a Breakpoint}
First, we set a breakpoint on the line where we invoke First, we set a breakpoint on the line where we invoke
\l{QTextEdit::}{setPlainText()} by clicking between the line number and \l{QTextEdit::}{setPlainText()} by clicking between the line number and the
the window border. Then, select \gui{Start Debugging} from the window border. Then, select \gui{Start Debugging} from the \gui{Debug} menu
\gui{Debug} menu or press \key{F5}. or press \key{F5}.
\endtable \endtable
Breakpoints are visible in the \gui{Breakpoints} view, shown below, in Breakpoints are visible in the \gui{Breakpoints} view, shown below, in
\gui{Debug} mode. If you wish to remove a breakpoint, simply right \gui{Debug} mode. If you wish to remove a breakpoint, simply right-click on
click on it and select \gui{Delete breakpoint} from the context menu. it and select \gui{Delete breakpoint} from the context menu.
\image qtcreator-setting-breakpoint2.png \image qtcreator-setting-breakpoint2.png
@@ -880,10 +884,10 @@
\image qtcreator-watcher.png \image qtcreator-watcher.png
Suppose we modify our \c{on_findButton_clicked()} function to move back Suppose we modify our \c{on_findButton_clicked()} function to move back to
to the start of the document and continue searching once the cursor the start of the document and continue searching once the cursor hits the
hits the end of the document. Adding this functionality can be done end of the document. Adding this functionality can be done with the code
with the code snippet below: snippet below:
\code \code
void TextFinder::on_findButton_clicked() void TextFinder::on_findButton_clicked()
@@ -915,9 +919,9 @@
} }
\endcode \endcode
However, if you compile and run this code, the application will not However, if you compile and run this code, the application will not work
work correctly due to a logic error. To locate this logic error, you correctly due to a logic error. To locate this logic error, you can step
can step through the code using the following buttons: through the code using the following buttons:
\image qtcreator-debugging-buttons.png \image qtcreator-debugging-buttons.png
*/ */
@@ -931,20 +935,20 @@
\title Tips and Tricks \title Tips and Tricks
\bold{Quick mode switch} \bold{Quickly Switching between Modes}
You can quickly switch between modes by pressing \key{Ctrl+1}, You can quickly switch between modes by pressing \key{Ctrl+1},
\key{Ctrl+2}, etc. \key{Ctrl+2}, and so on.
\bold{Other keyboard shortcuts} \bold{Keyboard Shortcuts}
There are a lot of other \l{keyboard-shortcuts}{keyboard shortcuts}. Qt Creator provides a lot of useful keyboard shortcuts. A complete list can
be found \l{Keyboard Shortcuts}{here}.
\bold{Command line} \bold{Running Qt Creator from the Command Line}
You can start Qt Creator from a command prompt with an already You can start Qt Creator from a command prompt with an existing session or
existing session or \c{.pro} file by giving the name as argument on the \c{.pro} file by giving the name as argument on the command line.
command line.
\bold{Sidebar} \bold{Sidebar}

View File

@@ -292,6 +292,7 @@ Use *Scope::useAt(unsigned index) const
void Scope::addUse(unsigned sourceOffset, Name *name) void Scope::addUse(unsigned sourceOffset, Name *name)
{ {
#ifdef CPLUSPLUS_WITH_USES
if (++_useCount == _allocatedUses) { if (++_useCount == _allocatedUses) {
_allocatedUses += 4; _allocatedUses += 4;
_uses = reinterpret_cast<Use *>(realloc(_uses, _allocatedUses * sizeof(Use))); _uses = reinterpret_cast<Use *>(realloc(_uses, _allocatedUses * sizeof(Use)));
@@ -303,6 +304,7 @@ void Scope::addUse(unsigned sourceOffset, Name *name)
else else
lastVisibleSymbol = _symbols[_symbolCount]; lastVisibleSymbol = _symbols[_symbolCount];
_uses[_useCount].init(sourceOffset, name, lastVisibleSymbol); _uses[_useCount].init(sourceOffset, name, lastVisibleSymbol);
#endif
} }
CPLUSPLUS_END_NAMESPACE CPLUSPLUS_END_NAMESPACE

View File

@@ -9,7 +9,8 @@ HEADERS += \
$$PWD/helpviewer.h \ $$PWD/helpviewer.h \
$$PWD/contentwindow.h \ $$PWD/contentwindow.h \
$$PWD/bookmarkmanager.h \ $$PWD/bookmarkmanager.h \
$$PWD/../namespace_global.h $$PWD/../namespace_global.h \
$$PWD/indexwindow.h
SOURCES += \ SOURCES += \
$$PWD/filternamedialog.cpp \ $$PWD/filternamedialog.cpp \
@@ -19,7 +20,7 @@ SOURCES += \
$$PWD/contentwindow.cpp \ $$PWD/contentwindow.cpp \
$$PWD/bookmarkmanager.cpp $$PWD/bookmarkmanager.cpp
FORMS += \ FORMS += \
$$PWD/filternamedialog.ui \ $$PWD/filternamedialog.ui \
$$PWD/topicchooser.ui \ $$PWD/topicchooser.ui \
$$PWD/bookmarkdialog.ui $$PWD/bookmarkdialog.ui

View File

@@ -61,11 +61,11 @@ Icons::Icons()
{ {
} }
QIcon Icons::iconForSymbol(Symbol *symbol) const QIcon Icons::iconForSymbol(const Symbol *symbol) const
{ {
if (symbol->isFunction() || (symbol->isDeclaration() && symbol->type()->isFunction())) if (symbol->isFunction() || (symbol->isDeclaration() && symbol->type()->isFunction()))
{ {
Function *function = symbol->asFunction(); const Function *function = symbol->asFunction();
if (!function) if (!function)
function = symbol->type()->asFunction(); function = symbol->type()->asFunction();

View File

@@ -47,7 +47,7 @@ class CPLUSPLUS_EXPORT Icons
public: public:
Icons(); Icons();
QIcon iconForSymbol(Symbol *symbol) const; QIcon iconForSymbol(const Symbol *symbol) const;
QIcon keywordIcon() const; QIcon keywordIcon() const;
QIcon macroIcon() const; QIcon macroIcon() const;

View File

@@ -235,9 +235,9 @@ bool ResolveExpression::visit(ExpressionListAST *)
return false; return false;
} }
bool ResolveExpression::visit(BinaryExpressionAST *) bool ResolveExpression::visit(BinaryExpressionAST *ast)
{ {
// nothing to do. accept(ast->left_expression);
return false; return false;
} }

View File

@@ -33,26 +33,65 @@
#include "filenamevalidatinglineedit.h" #include "filenamevalidatinglineedit.h"
#include <QtCore/QRegExp>
#include <QtCore/QDebug>
namespace Core { namespace Core {
namespace Utils { namespace Utils {
FileNameValidatingLineEdit::FileNameValidatingLineEdit(QWidget *parent) :
BaseValidatingLineEdit(parent)
{
}
/* Validate a file base name, check for forbidden characters/strings. */
static const char *notAllowedChars = "/?:&\\*\"|#%<> ";
static const char *notAllowedSubStrings[] = {".."};
// Naming a file like a device name will break on Windows, even if it is // Naming a file like a device name will break on Windows, even if it is
// "com1.txt". Since we are cross-platform, we generally disallow such file // "com1.txt". Since we are cross-platform, we generally disallow such file
// names. // names.
static const char *notAllowedStrings[] = {"CON", "AUX", "PRN", "COM1", "COM2", "LPT1", "LPT2" }; static const QRegExp &windowsDeviceNoSubDirPattern()
{
static const QRegExp rc(QLatin1String("CON|AUX|PRN|COM1|COM2|LPT1|LPT2|NUL"),
Qt::CaseInsensitive);
Q_ASSERT(rc.isValid());
return rc;
}
bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *errorMessage /* = 0*/) static const QRegExp &windowsDeviceSubDirPattern()
{
static const QRegExp rc(QLatin1String(".*[/\\\\]CON|.*[/\\\\]AUX|.*[/\\\\]PRN|.*[/\\\\]COM1|.*[/\\\\]COM2|.*[/\\\\]LPT1|.*[/\\\\]LPT2|.*[/\\\\]NUL"),
Qt::CaseInsensitive);
Q_ASSERT(rc.isValid());
return rc;
}
// ----------- FileNameValidatingLineEdit
FileNameValidatingLineEdit::FileNameValidatingLineEdit(QWidget *parent) :
BaseValidatingLineEdit(parent),
m_allowDirectories(false),
m_unused(0)
{
}
bool FileNameValidatingLineEdit::allowDirectories() const
{
return m_allowDirectories;
}
void FileNameValidatingLineEdit::setAllowDirectories(bool v)
{
m_allowDirectories = v;
}
/* Validate a file base name, check for forbidden characters/strings. */
#ifdef Q_OS_WIN
# define SLASHES "/\\"
#else
# define SLASHES "/"
#endif
static const char *notAllowedCharsSubDir = "?:&*\"|#%<> ";
static const char *notAllowedCharsNoSubDir = "?:&*\"|#%<> "SLASHES;
static const char *notAllowedSubStrings[] = {".."};
bool FileNameValidatingLineEdit::validateFileName(const QString &name,
bool allowDirectories,
QString *errorMessage /* = 0*/)
{ {
if (name.isEmpty()) { if (name.isEmpty()) {
if (errorMessage) if (errorMessage)
@@ -60,6 +99,7 @@ bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *
return false; return false;
} }
// Characters // Characters
const char *notAllowedChars = allowDirectories ? notAllowedCharsSubDir : notAllowedCharsNoSubDir;
for (const char *c = notAllowedChars; *c; c++) for (const char *c = notAllowedChars; *c; c++)
if (name.contains(QLatin1Char(*c))) { if (name.contains(QLatin1Char(*c))) {
if (errorMessage) if (errorMessage)
@@ -76,22 +116,22 @@ bool FileNameValidatingLineEdit::validateFileName(const QString &name, QString *
return false; return false;
} }
} }
// Strings // Windows devices
const int notAllowedStringCount = sizeof(notAllowedStrings)/sizeof(const char *); bool matchesWinDevice = windowsDeviceNoSubDirPattern().exactMatch(name);
for (int s = 0; s < notAllowedStringCount; s++) { if (!matchesWinDevice && allowDirectories)
const QLatin1String notAllowedString(notAllowedStrings[s]); matchesWinDevice = windowsDeviceSubDirPattern().exactMatch(name);
if (name == notAllowedString) { if (matchesWinDevice) {
if (errorMessage) if (errorMessage)
*errorMessage = tr("The name must not be '%1'.").arg(QString(notAllowedString)); *errorMessage = tr("The name must not match that of a MS Windows device. (%1).").
return false; arg(windowsDeviceNoSubDirPattern().pattern().replace(QLatin1Char('|'), QLatin1Char(',')));
} return false;
} }
return true; return true;
} }
bool FileNameValidatingLineEdit::validate(const QString &value, QString *errorMessage) const bool FileNameValidatingLineEdit::validate(const QString &value, QString *errorMessage) const
{ {
return validateFileName(value, errorMessage); return validateFileName(value, m_allowDirectories, errorMessage);
} }
} // namespace Utils } // namespace Utils

View File

@@ -43,14 +43,23 @@ class QWORKBENCH_UTILS_EXPORT FileNameValidatingLineEdit : public BaseValidating
{ {
Q_OBJECT Q_OBJECT
Q_DISABLE_COPY(FileNameValidatingLineEdit) Q_DISABLE_COPY(FileNameValidatingLineEdit)
Q_PROPERTY(bool allowDirectories READ allowDirectories WRITE setAllowDirectories)
public: public:
explicit FileNameValidatingLineEdit(QWidget *parent = 0); explicit FileNameValidatingLineEdit(QWidget *parent = 0);
static bool validateFileName(const QString &name, QString *errorMessage /* = 0*/); static bool validateFileName(const QString &name,
bool allowDirectories = false,
QString *errorMessage = 0);
bool allowDirectories() const;
void setAllowDirectories(bool v);
protected: protected:
virtual bool validate(const QString &value, QString *errorMessage) const; virtual bool validate(const QString &value, QString *errorMessage) const;
private:
bool m_allowDirectories;
void *m_unused;
}; };
} // namespace Utils } // namespace Utils

View File

@@ -123,7 +123,7 @@ void FileWizardPage::slotActivated()
bool FileWizardPage::validateBaseName(const QString &name, QString *errorMessage /* = 0*/) bool FileWizardPage::validateBaseName(const QString &name, QString *errorMessage /* = 0*/)
{ {
return FileNameValidatingLineEdit::validateFileName(name, errorMessage); return FileNameValidatingLineEdit::validateFileName(name, false, errorMessage);
} }
} // namespace Utils } // namespace Utils

View File

@@ -346,6 +346,21 @@ void NewClassWidget::setFormExtension(const QString &e)
m_d->m_formExtension = fixSuffix(e); m_d->m_formExtension = fixSuffix(e);
} }
bool NewClassWidget::allowDirectories() const
{
return m_d->m_ui.headerFileLineEdit->allowDirectories();
}
void NewClassWidget::setAllowDirectories(bool v)
{
// We keep all in sync
if (allowDirectories() != v) {
m_d->m_ui.sourceFileLineEdit->setAllowDirectories(v);
m_d->m_ui.headerFileLineEdit->setAllowDirectories(v);
m_d->m_ui.formFileLineEdit->setAllowDirectories(v);
}
}
void NewClassWidget::slotValidChanged() void NewClassWidget::slotValidChanged()
{ {
const bool newValid = isValid(); const bool newValid = isValid();

View File

@@ -73,6 +73,7 @@ class QWORKBENCH_UTILS_EXPORT NewClassWidget : public QWidget
Q_PROPERTY(QString formExtension READ formExtension WRITE setFormExtension DESIGNABLE true) Q_PROPERTY(QString formExtension READ formExtension WRITE setFormExtension DESIGNABLE true)
Q_PROPERTY(bool formInputCheckable READ formInputCheckable WRITE setFormInputCheckable DESIGNABLE true) Q_PROPERTY(bool formInputCheckable READ formInputCheckable WRITE setFormInputCheckable DESIGNABLE true)
Q_PROPERTY(bool formInputChecked READ formInputChecked WRITE setFormInputChecked DESIGNABLE true) Q_PROPERTY(bool formInputChecked READ formInputChecked WRITE setFormInputChecked DESIGNABLE true)
Q_PROPERTY(bool allowDirectories READ allowDirectories WRITE setAllowDirectories)
// Utility "USER" property for wizards containing file names. // Utility "USER" property for wizards containing file names.
Q_PROPERTY(QStringList files READ files DESIGNABLE false USER true) Q_PROPERTY(QStringList files READ files DESIGNABLE false USER true)
public: public:
@@ -97,7 +98,7 @@ public:
QString sourceExtension() const; QString sourceExtension() const;
QString headerExtension() const; QString headerExtension() const;
QString formExtension() const; QString formExtension() const;
bool allowDirectories() const;
bool isValid(QString *error = 0) const; bool isValid(QString *error = 0) const;
@@ -125,6 +126,7 @@ public slots:
void setSourceExtension(const QString &e); void setSourceExtension(const QString &e);
void setHeaderExtension(const QString &e); void setHeaderExtension(const QString &e);
void setFormExtension(const QString &e); void setFormExtension(const QString &e);
void setAllowDirectories(bool v);
/* Suggest a class name from the base class by stripping the leading 'Q' /* Suggest a class name from the base class by stripping the leading 'Q'
* character. This will happen automagically if the base class combo * character. This will happen automagically if the base class combo

View File

@@ -30,6 +30,7 @@
** version 1.2, included in the file GPL_EXCEPTION.txt in this package. ** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
** **
***************************************************************************/ ***************************************************************************/
#ifndef PATHCHOOSER_H #ifndef PATHCHOOSER_H
#define PATHCHOOSER_H #define PATHCHOOSER_H

View File

@@ -45,7 +45,7 @@ ProjectNameValidatingLineEdit::ProjectNameValidatingLineEdit(QWidget *parent)
bool ProjectNameValidatingLineEdit::validateProjectName(const QString &name, QString *errorMessage /* = 0*/) bool ProjectNameValidatingLineEdit::validateProjectName(const QString &name, QString *errorMessage /* = 0*/)
{ {
// Validation is file name + checking for dots // Validation is file name + checking for dots
if (!FileNameValidatingLineEdit::validateFileName(name, errorMessage)) if (!FileNameValidatingLineEdit::validateFileName(name, false, errorMessage))
return false; return false;
// We don't want dots in the directory name for some legacy Windows // We don't want dots in the directory name for some legacy Windows

View File

@@ -125,6 +125,7 @@ struct SynchronousProcessPrivate {
SynchronousProcessResponse m_result; SynchronousProcessResponse m_result;
int m_hangTimerCount; int m_hangTimerCount;
int m_maxHangTimerCount; int m_maxHangTimerCount;
bool m_startFailure;
ChannelBuffer m_stdOut; ChannelBuffer m_stdOut;
ChannelBuffer m_stdErr; ChannelBuffer m_stdErr;
@@ -133,7 +134,8 @@ struct SynchronousProcessPrivate {
SynchronousProcessPrivate::SynchronousProcessPrivate() : SynchronousProcessPrivate::SynchronousProcessPrivate() :
m_stdOutCodec(0), m_stdOutCodec(0),
m_hangTimerCount(0), m_hangTimerCount(0),
m_maxHangTimerCount(defaultMaxHangTimerCount) m_maxHangTimerCount(defaultMaxHangTimerCount),
m_startFailure(false)
{ {
} }
@@ -143,6 +145,7 @@ void SynchronousProcessPrivate::clearForRun()
m_stdOut.clearForRun(); m_stdOut.clearForRun();
m_stdErr.clearForRun(); m_stdErr.clearForRun();
m_result.clear(); m_result.clear();
m_startFailure = false;
} }
// ----------- SynchronousProcess // ----------- SynchronousProcess
@@ -221,23 +224,27 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
qDebug() << '>' << Q_FUNC_INFO << binary << args; qDebug() << '>' << Q_FUNC_INFO << binary << args;
m_d->clearForRun(); m_d->clearForRun();
m_d->m_timer.start();
QApplication::setOverrideCursor(Qt::WaitCursor);
// On Windows, start failure is triggered immediately if the
// executable cannot be found in the path. Do not start the
// event loop in that case.
m_d->m_process.start(binary, args, QIODevice::ReadOnly); m_d->m_process.start(binary, args, QIODevice::ReadOnly);
m_d->m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents); if (!m_d->m_startFailure) {
if (m_d->m_result.result == SynchronousProcessResponse::Finished || m_d->m_result.result == SynchronousProcessResponse::FinishedError) { m_d->m_timer.start();
processStdOut(false); QApplication::setOverrideCursor(Qt::WaitCursor);
processStdErr(false); m_d->m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
if (m_d->m_result.result == SynchronousProcessResponse::Finished || m_d->m_result.result == SynchronousProcessResponse::FinishedError) {
processStdOut(false);
processStdErr(false);
}
m_d->m_result.stdOut = convertStdOut(m_d->m_stdOut.data);
m_d->m_result.stdErr = convertStdErr(m_d->m_stdErr.data);
m_d->m_timer.stop();
QApplication::restoreOverrideCursor();
} }
m_d->m_result.stdOut = convertStdOut(m_d->m_stdOut.data);
m_d->m_result.stdErr = convertStdErr(m_d->m_stdErr.data);
m_d->m_timer.stop();
QApplication::restoreOverrideCursor();
if (debug) if (debug)
qDebug() << '<' << Q_FUNC_INFO << binary << m_d->m_result; qDebug() << '<' << Q_FUNC_INFO << binary << m_d->m_result;
return m_d->m_result; return m_d->m_result;
@@ -246,12 +253,14 @@ SynchronousProcessResponse SynchronousProcess::run(const QString &binary,
void SynchronousProcess::slotTimeout() void SynchronousProcess::slotTimeout()
{ {
if (++m_d->m_hangTimerCount > m_d->m_maxHangTimerCount) { if (++m_d->m_hangTimerCount > m_d->m_maxHangTimerCount) {
if (debug)
qDebug() << Q_FUNC_INFO << "HANG detected, killing";
m_d->m_process.kill(); m_d->m_process.kill();
m_d->m_result.result = SynchronousProcessResponse::Hang; m_d->m_result.result = SynchronousProcessResponse::Hang;
} else {
if (debug)
qDebug() << Q_FUNC_INFO << m_d->m_hangTimerCount;
} }
if (debug)
qDebug() << Q_FUNC_INFO << m_d->m_hangTimerCount;
} }
void SynchronousProcess::finished(int exitCode, QProcess::ExitStatus e) void SynchronousProcess::finished(int exitCode, QProcess::ExitStatus e)
@@ -265,7 +274,9 @@ void SynchronousProcess::finished(int exitCode, QProcess::ExitStatus e)
m_d->m_result.exitCode = exitCode; m_d->m_result.exitCode = exitCode;
break; break;
case QProcess::CrashExit: case QProcess::CrashExit:
m_d->m_result.result = SynchronousProcessResponse::TerminatedAbnormally; // Was hang detected before and killed?
if (m_d->m_result.result != SynchronousProcessResponse::Hang)
m_d->m_result.result = SynchronousProcessResponse::TerminatedAbnormally;
m_d->m_result.exitCode = -1; m_d->m_result.exitCode = -1;
break; break;
} }
@@ -277,7 +288,10 @@ void SynchronousProcess::error(QProcess::ProcessError e)
m_d->m_hangTimerCount = 0; m_d->m_hangTimerCount = 0;
if (debug) if (debug)
qDebug() << Q_FUNC_INFO << e; qDebug() << Q_FUNC_INFO << e;
m_d->m_result.result = SynchronousProcessResponse::StartFailed; // Was hang detected before and killed?
if (m_d->m_result.result != SynchronousProcessResponse::Hang)
m_d->m_result.result = SynchronousProcessResponse::StartFailed;
m_d->m_startFailure = true;
m_d->m_eventLoop.quit(); m_d->m_eventLoop.quit();
} }

View File

@@ -127,6 +127,7 @@ MainWindow::MainWindow() :
m_mimeDatabase(new MimeDatabase), m_mimeDatabase(new MimeDatabase),
m_navigationWidget(0), m_navigationWidget(0),
m_rightPaneWidget(0), m_rightPaneWidget(0),
m_versionDialog(0),
m_activeContext(0), m_activeContext(0),
m_pluginManager(0), m_pluginManager(0),
m_outputPane(new OutputPane(m_globalContext)), m_outputPane(new OutputPane(m_globalContext)),
@@ -1085,8 +1086,20 @@ void MainWindow::openRecentFile()
void MainWindow::aboutQtCreator() void MainWindow::aboutQtCreator()
{ {
VersionDialog versionDialog(this); if (!m_versionDialog) {
versionDialog.exec(); m_versionDialog = new VersionDialog(this);
connect(m_versionDialog, SIGNAL(finished(int)),
this, SLOT(destroyVersionDialog()));
}
m_versionDialog->show();
}
void MainWindow::destroyVersionDialog()
{
if (m_versionDialog) {
m_versionDialog->deleteLater();
m_versionDialog = 0;
}
} }
void MainWindow::aboutPlugins() void MainWindow::aboutPlugins()

View File

@@ -83,6 +83,7 @@ class OutputPane;
class ProgressManager; class ProgressManager;
class ShortcutSettings; class ShortcutSettings;
class ViewManager; class ViewManager;
class VersionDialog;
class CORE_EXPORT MainWindow : public QMainWindow class CORE_EXPORT MainWindow : public QMainWindow
{ {
@@ -160,6 +161,7 @@ private slots:
void aboutPlugins(); void aboutPlugins();
void updateFocusWidget(QWidget *old, QWidget *now); void updateFocusWidget(QWidget *old, QWidget *now);
void toggleNavigation(); void toggleNavigation();
void destroyVersionDialog();
private: private:
void updateContextObject(IContext *context); void updateContextObject(IContext *context);
@@ -190,6 +192,7 @@ private:
NavigationWidget *m_navigationWidget; NavigationWidget *m_navigationWidget;
RightPaneWidget *m_rightPaneWidget; RightPaneWidget *m_rightPaneWidget;
Core::BaseView *m_outputView; Core::BaseView *m_outputView;
VersionDialog *m_versionDialog;
IContext * m_activeContext; IContext * m_activeContext;

View File

@@ -73,6 +73,7 @@ ClassNamePage::ClassNamePage(const QString &sourceSuffix,
m_newClassWidget->setBaseClassEditable(true); m_newClassWidget->setBaseClassEditable(true);
m_newClassWidget->setFormInputVisible(false); m_newClassWidget->setFormInputVisible(false);
m_newClassWidget->setNamespacesEnabled(true); m_newClassWidget->setNamespacesEnabled(true);
m_newClassWidget->setAllowDirectories(true);
connect(m_newClassWidget, SIGNAL(validChanged()), connect(m_newClassWidget, SIGNAL(validChanged()),
this, SLOT(slotValidChanged())); this, SLOT(slotValidChanged()));

View File

@@ -206,6 +206,7 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable)
connect(m_methodCombo, SIGNAL(activated(int)), this, SLOT(jumpToMethod(int))); connect(m_methodCombo, SIGNAL(activated(int)), this, SLOT(jumpToMethod(int)));
connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateMethodBoxIndex())); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateMethodBoxIndex()));
connect(m_methodCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMethodBoxToolTip()));
connect(file(), SIGNAL(changed()), this, SLOT(updateFileName())); connect(file(), SIGNAL(changed()), this, SLOT(updateFileName()));
@@ -355,10 +356,16 @@ void CPPEditor::updateMethodBoxIndex()
if (lastIndex.isValid()) { if (lastIndex.isValid()) {
bool blocked = m_methodCombo->blockSignals(true); bool blocked = m_methodCombo->blockSignals(true);
m_methodCombo->setCurrentIndex(lastIndex.row()); m_methodCombo->setCurrentIndex(lastIndex.row());
updateMethodBoxToolTip();
(void) m_methodCombo->blockSignals(blocked); (void) m_methodCombo->blockSignals(blocked);
} }
} }
void CPPEditor::updateMethodBoxToolTip()
{
m_methodCombo->setToolTip(m_methodCombo->currentText());
}
static bool isCompatible(Name *name, Name *otherName) static bool isCompatible(Name *name, Name *otherName)
{ {
if (NameId *nameId = name->asNameId()) { if (NameId *nameId = name->asNameId()) {

View File

@@ -115,7 +115,7 @@ private slots:
void updateFileName(); void updateFileName();
void jumpToMethod(int index); void jumpToMethod(int index);
void updateMethodBoxIndex(); void updateMethodBoxIndex();
void updateMethodBoxToolTip();
void onDocumentUpdated(CPlusPlus::Document::Ptr doc); void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
private: private:

View File

@@ -0,0 +1,50 @@
/***************************************************************************
**
** 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.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "cppclassesfilter.h"
using namespace CppTools::Internal;
CppClassesFilter::CppClassesFilter(CppModelManager *manager, Core::EditorManager *editorManager)
: CppQuickOpenFilter(manager, editorManager)
{
setShortcutString("c");
setIncludedByDefault(false);
search.setSymbolsToSearchFor(SearchSymbols::Classes);
search.setSeparateScope(true);
}
CppClassesFilter::~CppClassesFilter()
{
}

View File

@@ -31,52 +31,28 @@
** **
***************************************************************************/ ***************************************************************************/
#ifndef INDEXWINDOW_H #ifndef CPPCLASSESFILTER_H
#define INDEXWINDOW_H #define CPPCLASSESFILTER_H
#include <QtCore/QUrl> #include <cppquickopenfilter.h>
#include <QtGui/QWidget>
#include <QtGui/QLineEdit>
QT_BEGIN_NAMESPACE namespace CppTools {
namespace Internal {
class QHelpIndexWidget; class CppClassesFilter : public CppQuickOpenFilter
class QHelpEngine;
class IndexWindow : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
IndexWindow(QHelpEngine *helpEngine, QWidget *parent = 0); CppClassesFilter(CppModelManager *manager, Core::EditorManager *editorManager);
~IndexWindow(); ~CppClassesFilter();
void setSearchLineEditText(const QString &text); QString trName() const { return tr("Classes"); }
QString searchLineEditText() const QString name() const { return QLatin1String("Classes"); }
{ Priority priority() const { return Medium; }
return m_searchLineEdit->text();
}
signals:
void linkActivated(const QUrl &link);
void linksActivated(const QMap<QString, QUrl> &links,
const QString &keyword);
void escapePressed();
private slots:
void filterIndices(const QString &filter);
void enableSearchLineEdit();
void disableSearchLineEdit();
private:
bool eventFilter(QObject *obj, QEvent *e);
void focusInEvent(QFocusEvent *e);
QLineEdit *m_searchLineEdit;
QHelpIndexWidget *m_indexWidget;
QHelpEngine *m_helpEngine;
}; };
QT_END_NAMESPACE } // namespace Internal
} // namespace CppTools
#endif // INDEXWINDOW_H #endif // CPPCLASSESFILTER_H

View File

@@ -60,7 +60,7 @@
using namespace CppTools::Internal; using namespace CppTools::Internal;
CppHoverHandler::CppHoverHandler(CppModelManager *manager, QObject *parent) CppHoverHandler::CppHoverHandler(CppModelManager *manager, QObject *parent)
: QObject(parent), m_manager(manager) : QObject(parent), m_manager(manager), m_helpEngineNeedsSetup(false)
{ {
QFileInfo fi(ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>()->settings()->fileName()); QFileInfo fi(ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>()->settings()->fileName());
m_helpEngine = new QHelpEngineCore(fi.absolutePath() m_helpEngine = new QHelpEngineCore(fi.absolutePath()
@@ -68,6 +68,7 @@ CppHoverHandler::CppHoverHandler(CppModelManager *manager, QObject *parent)
//m_helpEngine->setAutoSaveFilter(false); //m_helpEngine->setAutoSaveFilter(false);
m_helpEngine->setupData(); m_helpEngine->setupData();
m_helpEngine->setCurrentFilter(tr("Unfiltered")); m_helpEngine->setCurrentFilter(tr("Unfiltered"));
m_helpEngineNeedsSetup = m_helpEngine->registeredDocumentations().count() == 0;
} }
void CppHoverHandler::updateContextHelpId(TextEditor::ITextEditor *editor, int pos) void CppHoverHandler::updateContextHelpId(TextEditor::ITextEditor *editor, int pos)
@@ -234,6 +235,12 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
} }
} }
if (m_helpEngineNeedsSetup
&& m_helpEngine->registeredDocumentations().count() > 0) {
m_helpEngine->setupData();
m_helpEngineNeedsSetup = false;
}
if (!m_helpId.isEmpty() && !m_helpEngine->linksForIdentifier(m_helpId).isEmpty()) { if (!m_helpId.isEmpty() && !m_helpEngine->linksForIdentifier(m_helpId).isEmpty()) {
m_toolTip = QString(QLatin1String("<table><tr><td valign=middle><nobr>%1</td>" m_toolTip = QString(QLatin1String("<table><tr><td valign=middle><nobr>%1</td>"
"<td><img src=\":/cpptools/images/f1.svg\"></td></tr></table>")).arg(Qt::escape(m_toolTip)); "<td><img src=\":/cpptools/images/f1.svg\"></td></tr></table>")).arg(Qt::escape(m_toolTip));

View File

@@ -68,6 +68,7 @@ private:
QHelpEngineCore *m_helpEngine; QHelpEngineCore *m_helpEngine;
QString m_helpId; QString m_helpId;
QString m_toolTip; QString m_toolTip;
bool m_helpEngineNeedsSetup;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -129,9 +129,12 @@ public:
void setProjectFiles(const QStringList &files) void setProjectFiles(const QStringList &files)
{ m_projectFiles = files; } { m_projectFiles = files; }
void operator()(QString &fileName) void run(QString &fileName)
{ sourceNeeded(fileName, IncludeGlobal); } { sourceNeeded(fileName, IncludeGlobal); }
void operator()(QString &fileName)
{ run(fileName); }
protected: protected:
bool includeFile(const QString &absoluteFilePath, QByteArray *result) bool includeFile(const QString &absoluteFilePath, QByteArray *result)
{ {
@@ -254,7 +257,7 @@ protected:
} }
virtual void startExpandingMacro(unsigned offset, virtual void startExpandingMacro(unsigned offset,
const rpp::Macro &macro, const rpp::Macro &,
const QByteArray &originalText) const QByteArray &originalText)
{ {
if (! m_currentDoc) if (! m_currentDoc)
@@ -264,7 +267,7 @@ protected:
m_currentDoc->addMacroUse(offset, originalText.length()); m_currentDoc->addMacroUse(offset, originalText.length());
} }
virtual void stopExpandingMacro(unsigned offset, const rpp::Macro &macro) virtual void stopExpandingMacro(unsigned, const rpp::Macro &)
{ {
if (! m_currentDoc) if (! m_currentDoc)
return; return;
@@ -409,6 +412,8 @@ CppModelManager::CppModelManager(QObject *parent) :
CppModelManagerInterface(parent), CppModelManagerInterface(parent),
m_core(ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>()) m_core(ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>())
{ {
m_dirty = true;
m_projectExplorer = ExtensionSystem::PluginManager::instance() m_projectExplorer = ExtensionSystem::PluginManager::instance()
->getObject<ProjectExplorer::ProjectExplorerPlugin>(); ->getObject<ProjectExplorer::ProjectExplorerPlugin>();
@@ -417,6 +422,9 @@ CppModelManager::CppModelManager(QObject *parent) :
ProjectExplorer::SessionManager *session = m_projectExplorer->session(); ProjectExplorer::SessionManager *session = m_projectExplorer->session();
Q_ASSERT(session != 0); Q_ASSERT(session != 0);
connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
this, SLOT(onProjectAdded(ProjectExplorer::Project*)));
connect(session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)), connect(session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)),
this, SLOT(onAboutToRemoveProject(ProjectExplorer::Project *))); this, SLOT(onAboutToRemoveProject(ProjectExplorer::Project *)));
@@ -448,7 +456,7 @@ Document::Ptr CppModelManager::document(const QString &fileName)
CppModelManager::DocumentTable CppModelManager::documents() CppModelManager::DocumentTable CppModelManager::documents()
{ return m_documents; } { return m_documents; }
QStringList CppModelManager::projectFiles() const QStringList CppModelManager::updateProjectFiles() const
{ {
QStringList files; QStringList files;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -460,7 +468,7 @@ QStringList CppModelManager::projectFiles() const
return files; return files;
} }
QStringList CppModelManager::includePaths() const QStringList CppModelManager::updateIncludePaths() const
{ {
QStringList includePaths; QStringList includePaths;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -472,7 +480,7 @@ QStringList CppModelManager::includePaths() const
return includePaths; return includePaths;
} }
QStringList CppModelManager::frameworkPaths() const QStringList CppModelManager::updateFrameworkPaths() const
{ {
QStringList frameworkPaths; QStringList frameworkPaths;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -484,7 +492,7 @@ QStringList CppModelManager::frameworkPaths() const
return frameworkPaths; return frameworkPaths;
} }
QByteArray CppModelManager::definedMacros() const QByteArray CppModelManager::updateDefinedMacros() const
{ {
QByteArray macros; QByteArray macros;
QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects); QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -496,7 +504,7 @@ QByteArray CppModelManager::definedMacros() const
return macros; return macros;
} }
QMap<QString, QByteArray> CppModelManager::buildWorkingCopyList() const QMap<QString, QByteArray> CppModelManager::buildWorkingCopyList()
{ {
QMap<QString, QByteArray> workingCopy; QMap<QString, QByteArray> workingCopy;
QMapIterator<TextEditor::ITextEditor *, CppEditorSupport *> it(m_editorSupport); QMapIterator<TextEditor::ITextEditor *, CppEditorSupport *> it(m_editorSupport);
@@ -527,8 +535,14 @@ QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles
if (! sourceFiles.isEmpty() && qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull()) { if (! sourceFiles.isEmpty() && qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull()) {
const QMap<QString, QByteArray> workingCopy = buildWorkingCopyList(); const QMap<QString, QByteArray> workingCopy = buildWorkingCopyList();
QFuture<void> result = QtConcurrent::run(&CppModelManager::parse, this, CppPreprocessor *preproc = new CppPreprocessor(this);
sourceFiles, workingCopy); preproc->setProjectFiles(projectFiles());
preproc->setIncludePaths(includePaths());
preproc->setFrameworkPaths(frameworkPaths());
preproc->setWorkingCopy(workingCopy);
QFuture<void> result = QtConcurrent::run(&CppModelManager::parse,
preproc, sourceFiles);
if (sourceFiles.count() > 1) { if (sourceFiles.count() > 1) {
m_core->progressManager()->addTask(result, tr("Indexing"), m_core->progressManager()->addTask(result, tr("Indexing"),
@@ -669,28 +683,35 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
sel.cursor = c; sel.cursor = c;
selections.append(sel); selections.append(sel);
} }
ed->setExtraExtraSelections(selections); ed->setExtraSelections(TextEditor::BaseTextEditor::CodeWarningsSelection, selections);
break; break;
} }
} }
} }
void CppModelManager::onProjectAdded(ProjectExplorer::Project *)
{
m_dirty = true;
}
void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project) void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project)
{ {
m_dirty = true;
m_projects.remove(project); m_projects.remove(project);
GC(); GC();
} }
void CppModelManager::onSessionUnloaded() void CppModelManager::onSessionUnloaded()
{ {
if (m_core->progressManager()) if (m_core->progressManager()) {
m_core->progressManager()->cancelTasks(CppTools::Constants::TASK_INDEX); m_core->progressManager()->cancelTasks(CppTools::Constants::TASK_INDEX);
m_dirty = true;
}
} }
void CppModelManager::parse(QFutureInterface<void> &future, void CppModelManager::parse(QFutureInterface<void> &future,
CppModelManager *model, CppPreprocessor *preproc,
QStringList files, QStringList files)
QMap<QString, QByteArray> workingCopy)
{ {
Q_ASSERT(! files.isEmpty()); Q_ASSERT(! files.isEmpty());
@@ -699,14 +720,8 @@ void CppModelManager::parse(QFutureInterface<void> &future,
future.setProgressRange(0, files.size()); future.setProgressRange(0, files.size());
CppPreprocessor preproc(model);
preproc.setWorkingCopy(workingCopy);
preproc.setProjectFiles(model->projectFiles());
preproc.setIncludePaths(model->includePaths());
preproc.setFrameworkPaths(model->frameworkPaths());
QString conf = QLatin1String(pp_configuration_file); QString conf = QLatin1String(pp_configuration_file);
(void) preproc(conf); (void) preproc->run(conf);
const int STEP = 10; const int STEP = 10;
@@ -725,7 +740,7 @@ void CppModelManager::parse(QFutureInterface<void> &future,
#endif #endif
QString fileName = files.at(i); QString fileName = files.at(i);
preproc(fileName); preproc->run(fileName);
if (! (i % STEP)) // Yields execution of the current thread. if (! (i % STEP)) // Yields execution of the current thread.
QThread::yieldCurrentThread(); QThread::yieldCurrentThread();
@@ -739,6 +754,8 @@ void CppModelManager::parse(QFutureInterface<void> &future,
// Restore the previous thread priority. // Restore the previous thread priority.
QThread::currentThread()->setPriority(QThread::NormalPriority); QThread::currentThread()->setPriority(QThread::NormalPriority);
delete preproc;
} }
void CppModelManager::GC() void CppModelManager::GC()
@@ -746,7 +763,7 @@ void CppModelManager::GC()
DocumentTable documents = m_documents; DocumentTable documents = m_documents;
QSet<QString> processed; QSet<QString> processed;
QStringList todo = m_projectFiles; QStringList todo = projectFiles();
while (! todo.isEmpty()) { while (! todo.isEmpty()) {
QString fn = todo.last(); QString fn = todo.last();

View File

@@ -58,6 +58,7 @@ namespace CppTools {
namespace Internal { namespace Internal {
class CppEditorSupport; class CppEditorSupport;
class CppPreprocessor;
class CppHoverHandler; class CppHoverHandler;
class CppModelManager : public CppModelManagerInterface class CppModelManager : public CppModelManagerInterface
@@ -97,18 +98,54 @@ private Q_SLOTS:
void onDocumentUpdated(CPlusPlus::Document::Ptr doc); void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
void onAboutToRemoveProject(ProjectExplorer::Project *project); void onAboutToRemoveProject(ProjectExplorer::Project *project);
void onSessionUnloaded(); void onSessionUnloaded();
void onProjectAdded(ProjectExplorer::Project *project);
private: private:
QMap<QString, QByteArray> buildWorkingCopyList() const; QMap<QString, QByteArray> buildWorkingCopyList();
QStringList projectFiles() const;
QStringList includePaths() const; QStringList projectFiles()
QStringList frameworkPaths() const; {
QByteArray definedMacros() const; ensureUpdated();
return m_projectFiles;
}
QStringList includePaths()
{
ensureUpdated();
return m_includePaths;
}
QStringList frameworkPaths()
{
ensureUpdated();
return m_frameworkPaths;
}
QByteArray definedMacros()
{
ensureUpdated();
return m_definedMacros;
}
QStringList updateProjectFiles() const;
QStringList updateIncludePaths() const;
QStringList updateFrameworkPaths() const;
QByteArray updateDefinedMacros() const;
void ensureUpdated() {
if (! m_dirty)
return;
m_projectFiles = updateProjectFiles();
m_includePaths = updateIncludePaths();
m_frameworkPaths = updateFrameworkPaths();
m_definedMacros = updateDefinedMacros();
m_dirty = false;
}
static void parse(QFutureInterface<void> &future, static void parse(QFutureInterface<void> &future,
CppModelManager *model, CppPreprocessor *preproc,
QStringList files, QStringList files);
QMap<QString, QByteArray> workingCopy);
private: private:
Core::ICore *m_core; Core::ICore *m_core;
@@ -116,8 +153,12 @@ private:
CppHoverHandler *m_hoverHandler; CppHoverHandler *m_hoverHandler;
DocumentTable m_documents; DocumentTable m_documents;
// List of available source files // cache
bool m_dirty;
QStringList m_projectFiles; QStringList m_projectFiles;
QStringList m_includePaths;
QStringList m_frameworkPaths;
QByteArray m_definedMacros;
// editor integration // editor integration
QMap<TextEditor::ITextEditor *, CppEditorSupport *> m_editorSupport; QMap<TextEditor::ITextEditor *, CppEditorSupport *> m_editorSupport;

View File

@@ -32,172 +32,13 @@
***************************************************************************/ ***************************************************************************/
#include "cppquickopenfilter.h" #include "cppquickopenfilter.h"
#include "cppmodelmanager.h"
#include <Literals.h> #include <coreplugin/editormanager/editormanager.h>
#include <Symbols.h>
#include <SymbolVisitor.h>
#include <Scope.h>
#include <cplusplus/Overview.h>
#include <cplusplus/Icons.h>
#include <coreplugin/editormanager/ieditor.h> #include <coreplugin/editormanager/ieditor.h>
#include <texteditor/itexteditor.h> #include <texteditor/itexteditor.h>
#include <texteditor/basetexteditor.h> #include <texteditor/basetexteditor.h>
#include <QtCore/QMultiMap>
#include <functional>
using namespace CPlusPlus;
namespace CppTools {
namespace Internal {
class SearchSymbols: public std::unary_function<Document::Ptr, QList<ModelItemInfo> >,
protected SymbolVisitor
{
Overview overview;
Icons icons;
QList<ModelItemInfo> items;
public:
QList<ModelItemInfo> operator()(Document::Ptr doc)
{ return operator()(doc, QString()); }
QList<ModelItemInfo> operator()(Document::Ptr doc, const QString &scope)
{
QString previousScope = switchScope(scope);
items.clear();
for (unsigned i = 0; i < doc->globalSymbolCount(); ++i) {
accept(doc->globalSymbolAt(i));
}
(void) switchScope(previousScope);
return items;
}
protected:
using SymbolVisitor::visit;
void accept(Symbol *symbol)
{ Symbol::visitSymbol(symbol, this); }
QString switchScope(const QString &scope)
{
QString previousScope = _scope;
_scope = scope;
return previousScope;
}
virtual bool visit(Enum *symbol)
{
QString name = symbolName(symbol);
QString previousScope = switchScope(name);
QIcon icon = icons.iconForSymbol(symbol);
Scope *members = symbol->members();
items.append(ModelItemInfo(name, QString(), ModelItemInfo::Enum,
QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
symbol->line(),
icon));
for (unsigned i = 0; i < members->symbolCount(); ++i) {
accept(members->symbolAt(i));
}
(void) switchScope(previousScope);
return false;
}
virtual bool visit(Function *symbol)
{
QString name = symbolName(symbol);
QString type = overview.prettyType(symbol->type());
QIcon icon = icons.iconForSymbol(symbol);
items.append(ModelItemInfo(name, type, ModelItemInfo::Method,
QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
symbol->line(),
icon));
return false;
}
virtual bool visit(Namespace *symbol)
{
QString name = symbolName(symbol);
QString previousScope = switchScope(name);
Scope *members = symbol->members();
for (unsigned i = 0; i < members->symbolCount(); ++i) {
accept(members->symbolAt(i));
}
(void) switchScope(previousScope);
return false;
}
#if 0
// This visit method would make function declaration be included in QuickOpen
virtual bool visit(Declaration *symbol)
{
if (symbol->type()->isFunction()) {
QString name = symbolName(symbol);
QString type = overview.prettyType(symbol->type());
//QIcon icon = ...;
items.append(ModelItemInfo(name, type, ModelItemInfo::Method,
QString::fromUtf8(symbol->fileName(), symbol->line()),
symbol->line()));
}
return false;
}
#endif
virtual bool visit(Class *symbol)
{
QString name = symbolName(symbol);
QString previousScope = switchScope(name);
QIcon icon = icons.iconForSymbol(symbol);
items.append(ModelItemInfo(name, QString(), ModelItemInfo::Class,
QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
symbol->line(),
icon));
Scope *members = symbol->members();
for (unsigned i = 0; i < members->symbolCount(); ++i) {
accept(members->symbolAt(i));
}
(void) switchScope(previousScope);
return false;
}
QString symbolName(Symbol *symbol) const
{
QString name = _scope;
if (! name.isEmpty())
name += QLatin1String("::");
QString symbolName = overview.prettyName(symbol->name());
if (symbolName.isEmpty()) {
QString type;
if (symbol->isNamespace()) {
type = QLatin1String("namespace");
} else if (symbol->isEnum()) {
type = QLatin1String("enum");
} else if (Class *c = symbol->asClass()) {
if (c->isUnion()) {
type = QLatin1String("union");
} else if (c->isStruct()) {
type = QLatin1String("struct");
} else {
type = QLatin1String("class");
}
} else {
type = QLatin1String("symbol");
}
symbolName = QLatin1String("<anonymous ");
symbolName += type;
symbolName += QLatin1String(">");
}
name += symbolName;
return name;
}
private:
QString _scope;
};
} // namespace Internal
} // namespace CppTools
using namespace CppTools::Internal; using namespace CppTools::Internal;
CppQuickOpenFilter::CppQuickOpenFilter(CppModelManager *manager, Core::EditorManager *editorManager) CppQuickOpenFilter::CppQuickOpenFilter(CppModelManager *manager, Core::EditorManager *editorManager)
@@ -225,9 +66,8 @@ void CppQuickOpenFilter::onDocumentUpdated(CPlusPlus::Document::Ptr doc)
void CppQuickOpenFilter::onAboutToRemoveFiles(const QStringList &files) void CppQuickOpenFilter::onAboutToRemoveFiles(const QStringList &files)
{ {
foreach (QString file, files) { foreach (const QString &file, files)
m_searchList.remove(file); m_searchList.remove(file);
}
} }
void CppQuickOpenFilter::refresh(QFutureInterface<void> &future) void CppQuickOpenFilter::refresh(QFutureInterface<void> &future)
@@ -245,7 +85,6 @@ QList<QuickOpen::FilterEntry> CppQuickOpenFilter::matchesFor(const QString &orig
return entries; return entries;
bool hasWildcard = (entry.contains('*') || entry.contains('?')); bool hasWildcard = (entry.contains('*') || entry.contains('?'));
SearchSymbols search;
QMutableMapIterator<QString, Info> it(m_searchList); QMutableMapIterator<QString, Info> it(m_searchList);
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
@@ -276,6 +115,5 @@ QList<QuickOpen::FilterEntry> CppQuickOpenFilter::matchesFor(const QString &orig
void CppQuickOpenFilter::accept(QuickOpen::FilterEntry selection) const void CppQuickOpenFilter::accept(QuickOpen::FilterEntry selection) const
{ {
ModelItemInfo info = qvariant_cast<CppTools::Internal::ModelItemInfo>(selection.internalData); ModelItemInfo info = qvariant_cast<CppTools::Internal::ModelItemInfo>(selection.internalData);
TextEditor::BaseTextEditor::openEditorAt(info.fileName, info.line); TextEditor::BaseTextEditor::openEditorAt(info.fileName, info.line);
} }

View File

@@ -34,45 +34,18 @@
#ifndef CPPQUICKOPENFILTER_H #ifndef CPPQUICKOPENFILTER_H
#define CPPQUICKOPENFILTER_H #define CPPQUICKOPENFILTER_H
#include "cppmodelmanager.h" #include "searchsymbols.h"
#include <cplusplus/CppDocument.h>
#include <coreplugin/editormanager/editormanager.h>
#include <quickopen/iquickopenfilter.h> #include <quickopen/iquickopenfilter.h>
#include <QtGui/QIcon>
#include <QFile> namespace Core {
#include <QMetaType> class EditorManager;
}
namespace CppTools { namespace CppTools {
namespace Internal { namespace Internal {
struct ModelItemInfo class CppModelManager;
{
enum ItemType { Enum, Class, Method };
ModelItemInfo()
{ }
ModelItemInfo(const QString &symbolName,
const QString &symbolType,
ItemType type,
const QString &fileName,
int line,
const QIcon &icon)
: symbolName(symbolName),
symbolType(symbolType),
type(type),
fileName(fileName),
line(line),
icon(icon)
{ }
QString symbolName;
QString symbolType;
ItemType type;
QString fileName;
int line;
QIcon icon;
};
class CppQuickOpenFilter : public QuickOpen::IQuickOpenFilter class CppQuickOpenFilter : public QuickOpen::IQuickOpenFilter
{ {
@@ -82,12 +55,15 @@ public:
~CppQuickOpenFilter(); ~CppQuickOpenFilter();
QString trName() const { return tr("Classes and Methods"); } QString trName() const { return tr("Classes and Methods"); }
QString name() const { return "Classes and Methods"; } QString name() const { return QLatin1String("Classes and Methods"); }
Priority priority() const { return Medium; } Priority priority() const { return Medium; }
QList<QuickOpen::FilterEntry> matchesFor(const QString &entry); QList<QuickOpen::FilterEntry> matchesFor(const QString &entry);
void accept(QuickOpen::FilterEntry selection) const; void accept(QuickOpen::FilterEntry selection) const;
void refresh(QFutureInterface<void> &future); void refresh(QFutureInterface<void> &future);
protected:
SearchSymbols search;
private slots: private slots:
void onDocumentUpdated(CPlusPlus::Document::Ptr doc); void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
void onAboutToRemoveFiles(const QStringList &files); void onAboutToRemoveFiles(const QStringList &files);
@@ -114,6 +90,4 @@ private:
} // namespace Internal } // namespace Internal
} // namespace CppTools } // namespace CppTools
Q_DECLARE_METATYPE(CppTools::Internal::ModelItemInfo)
#endif // CPPQUICKOPENFILTER_H #endif // CPPQUICKOPENFILTER_H

View File

@@ -32,6 +32,7 @@
***************************************************************************/ ***************************************************************************/
#include "cpptools.h" #include "cpptools.h"
#include "cppclassesfilter.h"
#include "cppcodecompletion.h" #include "cppcodecompletion.h"
#include "cpphoverhandler.h" #include "cpphoverhandler.h"
#include "cppmodelmanager.h" #include "cppmodelmanager.h"
@@ -87,6 +88,7 @@ bool CppToolsPlugin::initialize(const QStringList & /*arguments*/, QString *)
CppQuickOpenFilter *quickOpenFilter = new CppQuickOpenFilter(m_modelManager, CppQuickOpenFilter *quickOpenFilter = new CppQuickOpenFilter(m_modelManager,
m_core->editorManager()); m_core->editorManager());
addAutoReleasedObject(quickOpenFilter); addAutoReleasedObject(quickOpenFilter);
addAutoReleasedObject(new CppClassesFilter(m_modelManager, m_core->editorManager()));
// Menus // Menus
Core::IActionContainer *mtools = am->actionContainer(Core::Constants::M_TOOLS); Core::IActionContainer *mtools = am->actionContainer(Core::Constants::M_TOOLS);

View File

@@ -4,31 +4,27 @@ include(../../qworkbenchplugin.pri)
include(../../plugins/quickopen/quickopen.pri) include(../../plugins/quickopen/quickopen.pri)
include(cpptools_dependencies.pri) include(cpptools_dependencies.pri)
#DEFINES += QT_NO_CAST_FROM_ASCII # DEFINES += QT_NO_CAST_FROM_ASCII
DEFINES += QT_NO_CAST_TO_ASCII DEFINES += QT_NO_CAST_TO_ASCII
unix:QMAKE_CXXFLAGS_DEBUG+=-O3 unix:QMAKE_CXXFLAGS_DEBUG += -O3
INCLUDEPATH += . INCLUDEPATH += .
DEFINES += CPPTOOLS_LIBRARY DEFINES += CPPTOOLS_LIBRARY
CONFIG += help CONFIG += help
include(rpp/rpp.pri)|error("Can't find RPP") include(rpp/rpp.pri)|error("Can't find RPP")
HEADERS += cpptools_global.h \
HEADERS += \ cppquickopenfilter.h \
cpptools_global.h \ cppclassesfilter.h \
cppquickopenfilter.h searchsymbols.h
SOURCES += cppquickopenfilter.cpp \
SOURCES += \ cpptoolseditorsupport.cpp \
cppquickopenfilter.cpp \ cppclassesfilter.cpp \
cpptoolseditorsupport.cpp searchsymbols.cpp
# Input # Input
SOURCES += cpptools.cpp \ SOURCES += cpptools.cpp \
cppmodelmanager.cpp \ cppmodelmanager.cpp \
cppcodecompletion.cpp \ cppcodecompletion.cpp \
cpphoverhandler.cpp cpphoverhandler.cpp
HEADERS += cpptools.h \ HEADERS += cpptools.h \
cppmodelmanager.h \ cppmodelmanager.h \
cppcodecompletion.h \ cppcodecompletion.h \
@@ -36,5 +32,4 @@ HEADERS += cpptools.h \
cppmodelmanagerinterface.h \ cppmodelmanagerinterface.h \
cpptoolseditorsupport.h \ cpptoolseditorsupport.h \
cpptoolsconstants.h cpptoolsconstants.h
RESOURCES += cpptools.qrc RESOURCES += cpptools.qrc

View File

@@ -0,0 +1,204 @@
/***************************************************************************
**
** 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.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "searchsymbols.h"
#include <Literals.h>
#include <Scope.h>
using namespace CPlusPlus;
using namespace CppTools::Internal;
SearchSymbols::SearchSymbols():
symbolsToSearchFor(Classes | Functions | Enums),
separateScope(false)
{
}
void SearchSymbols::setSymbolsToSearchFor(SymbolTypes types)
{
symbolsToSearchFor = types;
}
void SearchSymbols::setSeparateScope(bool separateScope)
{
this->separateScope = separateScope;
}
QList<ModelItemInfo> SearchSymbols::operator()(Document::Ptr doc, const QString &scope)
{
QString previousScope = switchScope(scope);
items.clear();
for (unsigned i = 0; i < doc->globalSymbolCount(); ++i) {
accept(doc->globalSymbolAt(i));
}
(void) switchScope(previousScope);
return items;
}
QString SearchSymbols::switchScope(const QString &scope)
{
QString previousScope = _scope;
_scope = scope;
return previousScope;
}
bool SearchSymbols::visit(Enum *symbol)
{
if (!(symbolsToSearchFor & Enums))
return false;
QString name = symbolName(symbol);
QString scopedName = scopedSymbolName(name);
QString previousScope = switchScope(scopedName);
appendItem(separateScope ? name : scopedName,
separateScope ? previousScope : QString(),
ModelItemInfo::Enum, symbol);
Scope *members = symbol->members();
for (unsigned i = 0; i < members->symbolCount(); ++i) {
accept(members->symbolAt(i));
}
(void) switchScope(previousScope);
return false;
}
bool SearchSymbols::visit(Function *symbol)
{
if (!(symbolsToSearchFor & Functions))
return false;
QString name = symbolName(symbol);
QString scopedName = scopedSymbolName(name);
QString type = overview.prettyType(symbol->type(),
separateScope ? symbol->name() : 0);
appendItem(separateScope ? type : scopedName,
separateScope ? _scope : type,
ModelItemInfo::Method, symbol);
return false;
}
bool SearchSymbols::visit(Namespace *symbol)
{
QString name = findOrInsert(scopedSymbolName(symbol));
QString previousScope = switchScope(name);
Scope *members = symbol->members();
for (unsigned i = 0; i < members->symbolCount(); ++i) {
accept(members->symbolAt(i));
}
(void) switchScope(previousScope);
return false;
}
#if 0
bool SearchSymbols::visit(Declaration *symbol)
{
if (symbol->type()->isFunction()) {
QString name = scopedSymbolName(symbol);
QString type = overview.prettyType(symbol->type());
appendItems(name, type, ModelItemInfo::Method, symbol->fileName());
}
return false;
}
#endif
bool SearchSymbols::visit(Class *symbol)
{
if (!(symbolsToSearchFor & Classes))
return false;
QString name = symbolName(symbol);
QString scopedName = scopedSymbolName(name);
QString previousScope = switchScope(scopedName);
appendItem(separateScope ? name : scopedName,
separateScope ? previousScope : QString(),
ModelItemInfo::Class, symbol);
Scope *members = symbol->members();
for (unsigned i = 0; i < members->symbolCount(); ++i) {
accept(members->symbolAt(i));
}
(void) switchScope(previousScope);
return false;
}
QString SearchSymbols::scopedSymbolName(const QString &symbolName) const
{
QString name = _scope;
if (! name.isEmpty())
name += QLatin1String("::");
name += symbolName;
return name;
}
QString SearchSymbols::scopedSymbolName(const Symbol *symbol) const
{
return scopedSymbolName(symbolName(symbol));
}
QString SearchSymbols::symbolName(const Symbol *symbol) const
{
QString symbolName = overview.prettyName(symbol->name());
if (symbolName.isEmpty()) {
QString type;
if (symbol->isNamespace()) {
type = QLatin1String("namespace");
} else if (symbol->isEnum()) {
type = QLatin1String("enum");
} else if (const Class *c = symbol->asClass()) {
if (c->isUnion()) {
type = QLatin1String("union");
} else if (c->isStruct()) {
type = QLatin1String("struct");
} else {
type = QLatin1String("class");
}
} else {
type = QLatin1String("symbol");
}
symbolName = QLatin1String("<anonymous ");
symbolName += type;
symbolName += QLatin1String(">");
}
return symbolName;
}
void SearchSymbols::appendItem(const QString &name,
const QString &info,
ModelItemInfo::ItemType type,
const CPlusPlus::Symbol *symbol)
{
const QIcon icon = icons.iconForSymbol(symbol);
items.append(ModelItemInfo(name, info, type,
QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
symbol->line(),
icon));
}

View File

@@ -0,0 +1,145 @@
/***************************************************************************
**
** 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.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef SEARCHSYMBOLS_H
#define SEARCHSYMBOLS_H
#include <cplusplus/CppDocument.h>
#include <cplusplus/Icons.h>
#include <cplusplus/Overview.h>
#include <Symbols.h>
#include <SymbolVisitor.h>
#include <QIcon>
#include <QMetaType>
#include <QString>
namespace CppTools {
namespace Internal {
struct ModelItemInfo
{
enum ItemType { Enum, Class, Method };
ModelItemInfo()
{ }
ModelItemInfo(const QString &symbolName,
const QString &symbolType,
ItemType type,
const QString &fileName,
int line,
const QIcon &icon)
: symbolName(symbolName),
symbolType(symbolType),
type(type),
fileName(fileName),
line(line),
icon(icon)
{ }
QString symbolName;
QString symbolType;
ItemType type;
QString fileName;
int line;
QIcon icon;
};
class SearchSymbols: public std::unary_function<CPlusPlus::Document::Ptr, QList<ModelItemInfo> >,
protected CPlusPlus::SymbolVisitor
{
public:
enum SymbolType {
Classes = 0x1,
Functions = 0x2,
Enums = 0x4
};
Q_DECLARE_FLAGS(SymbolTypes, SymbolType)
SearchSymbols();
void setSymbolsToSearchFor(SymbolTypes types);
void setSeparateScope(bool separateScope);
QList<ModelItemInfo> operator()(CPlusPlus::Document::Ptr doc)
{ return operator()(doc, QString()); }
QList<ModelItemInfo> operator()(CPlusPlus::Document::Ptr doc, const QString &scope);
protected:
using SymbolVisitor::visit;
void accept(CPlusPlus::Symbol *symbol)
{ CPlusPlus::Symbol::visitSymbol(symbol, this); }
QString switchScope(const QString &scope);
virtual bool visit(CPlusPlus::Enum *symbol);
virtual bool visit(CPlusPlus::Function *symbol);
virtual bool visit(CPlusPlus::Namespace *symbol);
#if 0
// This visit method would make function declaration be included in QuickOpen
virtual bool visit(CPlusPlus::Declaration *symbol);
#endif
virtual bool visit(CPlusPlus::Class *symbol);
QString scopedSymbolName(const QString &symbolName) const;
QString scopedSymbolName(const CPlusPlus::Symbol *symbol) const;
QString symbolName(const CPlusPlus::Symbol *symbol) const;
void appendItem(const QString &name,
const QString &info,
ModelItemInfo::ItemType type,
const CPlusPlus::Symbol *symbol);
private:
QString findOrInsert(const QString &s)
{ return *strings.insert(s); }
QSet<QString> strings; // Used to avoid QString duplication
QString _scope;
CPlusPlus::Overview overview;
CPlusPlus::Icons icons;
QList<ModelItemInfo> items;
SymbolTypes symbolsToSearchFor;
bool separateScope;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(SearchSymbols::SymbolTypes)
} // namespace Internal
} // namespace CppTools
Q_DECLARE_METATYPE(CppTools::Internal::ModelItemInfo)
#endif // SEARCHSYMBOLS_H

View File

@@ -317,10 +317,20 @@ void DebuggerManager::init()
m_debugDumpersAction = new QAction(this); m_debugDumpersAction = new QAction(this);
m_debugDumpersAction->setText(tr("Debug Custom Dumpers")); m_debugDumpersAction->setText(tr("Debug Custom Dumpers"));
m_debugDumpersAction->setToolTip(tr("This is an internal tool to "
"make debugging the Custom Data Dumper code easier. "
"Using this action is in general not needed unless you "
"want do debug Qt Creator itself."));
m_debugDumpersAction->setCheckable(true); m_debugDumpersAction->setCheckable(true);
m_skipKnownFramesAction = new QAction(this); m_skipKnownFramesAction = new QAction(this);
m_skipKnownFramesAction->setText(tr("Skip Known Frames When Stepping")); m_skipKnownFramesAction->setText(tr("Skip Known Frames When Stepping"));
m_skipKnownFramesAction->setToolTip(tr("After checking this option"
"'Step Into' combines in certain situations several steps, "
"leading to 'less noisy' debugging. So will, e.g., the atomic "
"reference counting code be skipped, and a single 'Step Into' "
"for a signal emission will end up directly in the slot connected "
"to it"));
m_skipKnownFramesAction->setCheckable(true); m_skipKnownFramesAction->setCheckable(true);
m_useCustomDumpersAction = new QAction(this); m_useCustomDumpersAction = new QAction(this);
@@ -330,13 +340,6 @@ void DebuggerManager::init()
m_useCustomDumpersAction->setCheckable(true); m_useCustomDumpersAction->setCheckable(true);
m_useCustomDumpersAction->setChecked(true); m_useCustomDumpersAction->setChecked(true);
m_useCustomDumpersAction = new QAction(this);
m_useCustomDumpersAction->setText(tr("Use Custom Display for Qt Objects"));
m_useCustomDumpersAction->setToolTip(tr("Checking this will make the debugger "
"try to use code to format certain data (QObject, QString, ...) nicely. "));
m_useCustomDumpersAction->setCheckable(true);
m_useCustomDumpersAction->setChecked(true);
m_useFastStartAction = new QAction(this); m_useFastStartAction = new QAction(this);
m_useFastStartAction->setText(tr("Fast Debugger Start")); m_useFastStartAction->setText(tr("Fast Debugger Start"));
m_useFastStartAction->setToolTip(tr("Checking this will make the debugger " m_useFastStartAction->setToolTip(tr("Checking this will make the debugger "

View File

@@ -1276,7 +1276,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
m_currentFrame = frame.findChild("addr").data() + '%' + m_currentFrame = frame.findChild("addr").data() + '%' +
frame.findChild("func").data() + '%'; frame.findChild("func").data() + '%';
QApplication::alert(q->mainWindow(), 200); QApplication::alert(q->mainWindow(), 3000);
sendCommand("-file-list-exec-source-files", GdbQuerySources); sendCommand("-file-list-exec-source-files", GdbQuerySources);
sendCommand("-break-list", BreakList); sendCommand("-break-list", BreakList);
QVariant var = QVariant::fromValue<GdbMi>(data); QVariant var = QVariant::fromValue<GdbMi>(data);

View File

@@ -63,6 +63,7 @@ FormClassWizardPage::FormClassWizardPage(QWidget * parent) :
m_ui->newClassWidget->setBaseClassInputVisible(false); m_ui->newClassWidget->setBaseClassInputVisible(false);
m_ui->newClassWidget->setNamespacesEnabled(true); m_ui->newClassWidget->setNamespacesEnabled(true);
m_ui->newClassWidget->setAllowDirectories(true);
connect(m_ui->newClassWidget, SIGNAL(validChanged()), this, SLOT(slotValidChanged())); connect(m_ui->newClassWidget, SIGNAL(validChanged()), this, SLOT(slotValidChanged()));

View File

@@ -162,7 +162,10 @@ int BaseTextFind::replaceAll(const QString &before, const QString &after,
QTextDocument::FindFlags findFlags) QTextDocument::FindFlags findFlags)
{ {
QTextCursor editCursor = textCursor(); QTextCursor editCursor = textCursor();
editCursor.movePosition(QTextCursor::Start); if (!m_findScope.isNull())
editCursor.setPosition(m_findScope.selectionStart());
else
editCursor.movePosition(QTextCursor::Start);
editCursor.beginEditBlock(); editCursor.beginEditBlock();
int count = 0; int count = 0;
QTextCursor found; QTextCursor found;

View File

@@ -80,16 +80,16 @@ void CommitData::clear()
panelInfo.clear(); panelInfo.clear();
panelData.clear(); panelData.clear();
commitFiles.clear(); stagedFiles.clear();
notUpdatedFiles.clear(); unstagedFiles.clear();
untrackedFiles.clear(); untrackedFiles.clear();
} }
QDebug operator<<(QDebug d, const CommitData &data) QDebug operator<<(QDebug d, const CommitData &data)
{ {
d << data.panelInfo << data.panelData; d << data.panelInfo << data.panelData;
d.nospace() << "Commit: " << data.commitFiles << " Not updated: " d.nospace() << "Commit: " << data.stagedFiles << " Not updated: "
<< data.notUpdatedFiles << " Untracked: " << data.untrackedFiles; << data.unstagedFiles << " Untracked: " << data.untrackedFiles;
return d; return d;
} }

View File

@@ -71,8 +71,8 @@ struct CommitData
void clear(); void clear();
GitSubmitEditorPanelInfo panelInfo; GitSubmitEditorPanelInfo panelInfo;
GitSubmitEditorPanelData panelData; GitSubmitEditorPanelData panelData;
QStringList commitFiles; QStringList stagedFiles;
QStringList notUpdatedFiles; QStringList unstagedFiles;
QStringList untrackedFiles; QStringList untrackedFiles;
}; };

View File

@@ -35,6 +35,7 @@
#include "gitplugin.h" #include "gitplugin.h"
#include "gitconstants.h" #include "gitconstants.h"
#include "commitdata.h" #include "commitdata.h"
#include "gitsubmiteditor.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
@@ -51,7 +52,9 @@
#include <QtCore/QFuture> #include <QtCore/QFuture>
#include <QtCore/QTime> #include <QtCore/QTime>
#include <QtGui/QErrorMessage> #include <QtGui/QMessageBox>
#include <QtGui/QMainWindow> // for msg box parent
#include <QtGui/QPushButton>
using namespace Git; using namespace Git;
using namespace Git::Internal; using namespace Git::Internal;
@@ -77,12 +80,24 @@ inline Core::IEditor* locateEditor(const Core::ICore *core, const char *property
return 0; return 0;
} }
static inline QString msgRepositoryNotFound(const QString &dir)
{
return GitClient::tr("Unable to determine the repository for %1.").arg(dir);
}
static inline QString msgParseFilesFailed()
{
return GitClient::tr("Unable to parse the file output.");
}
// Format a command for the status window
static QString formatCommand(const QString &binary, const QStringList &args) static QString formatCommand(const QString &binary, const QStringList &args)
{ {
const QString timeStamp = QTime::currentTime().toString(QLatin1String("HH:mm")); const QString timeStamp = QTime::currentTime().toString(QLatin1String("HH:mm"));
return GitClient::tr("%1 Executing: %2 %3\n").arg(timeStamp, binary, args.join(QString(QLatin1Char(' ')))); return GitClient::tr("%1 Executing: %2 %3\n").arg(timeStamp, binary, args.join(QString(QLatin1Char(' '))));
} }
// ---------------- GitClient
GitClient::GitClient(GitPlugin* plugin, Core::ICore *core) : GitClient::GitClient(GitPlugin* plugin, Core::ICore *core) :
m_msgWait(tr("Waiting for data...")), m_msgWait(tr("Waiting for data...")),
m_plugin(plugin), m_plugin(plugin),
@@ -311,6 +326,19 @@ bool GitClient::synchronousAdd(const QString &workingDirectory, const QStringLis
bool GitClient::synchronousReset(const QString &workingDirectory, bool GitClient::synchronousReset(const QString &workingDirectory,
const QStringList &files) const QStringList &files)
{
QString errorMessage;
const bool rc = synchronousReset(workingDirectory, files, &errorMessage);
if (!rc) {
m_plugin->outputWindow()->append(errorMessage);
m_plugin->outputWindow()->popup(false);
}
return rc;
}
bool GitClient::synchronousReset(const QString &workingDirectory,
const QStringList &files,
QString *errorMessage)
{ {
if (Git::Constants::debug) if (Git::Constants::debug)
qDebug() << Q_FUNC_INFO << workingDirectory << files; qDebug() << Q_FUNC_INFO << workingDirectory << files;
@@ -325,9 +353,25 @@ bool GitClient::synchronousReset(const QString &workingDirectory,
// Note that git exits with 1 even if the operation is successful // Note that git exits with 1 even if the operation is successful
// Assume real failure if the output does not contain "foo.cpp modified" // Assume real failure if the output does not contain "foo.cpp modified"
if (!rc && !output.contains(QLatin1String("modified"))) { if (!rc && !output.contains(QLatin1String("modified"))) {
const QString errorMessage = tr("Unable to reset %n file(s) in %1: %2", 0, files.size()). *errorMessage = tr("Unable to reset %n file(s) in %1: %2", 0, files.size()).arg(workingDirectory, QString::fromLocal8Bit(errorText));
arg(workingDirectory, QString::fromLocal8Bit(errorText)); return false;
m_plugin->outputWindow()->append(errorMessage); }
return true;
}
bool GitClient::synchronousCheckout(const QString &workingDirectory,
const QStringList &files,
QString *errorMessage)
{
if (Git::Constants::debug)
qDebug() << Q_FUNC_INFO << workingDirectory << files;
QByteArray outputText;
QByteArray errorText;
QStringList arguments;
arguments << QLatin1String("checkout") << QLatin1String("--") << files;
const bool rc = synchronousGit(workingDirectory, arguments, &outputText, &errorText);
if (!rc) {
*errorMessage = tr("Unable to checkout %n file(s) in %1: %2", 0, files.size()).arg(workingDirectory, QString::fromLocal8Bit(errorText));
return false; return false;
} }
return true; return true;
@@ -365,16 +409,18 @@ void GitClient::executeGit(const QString &workingDirectory, const QStringList &a
command->execute(arguments, workingDirectory, environment); command->execute(arguments, workingDirectory, environment);
} }
bool GitClient::synchronousGit(const QString &workingDirectory bool GitClient::synchronousGit(const QString &workingDirectory,
, const QStringList &arguments const QStringList &arguments,
, QByteArray* outputText QByteArray* outputText,
, QByteArray* errorText) QByteArray* errorText,
bool logCommandToWindow)
{ {
if (Git::Constants::debug) if (Git::Constants::debug)
qDebug() << "synchronousGit" << workingDirectory << arguments; qDebug() << "synchronousGit" << workingDirectory << arguments;
const QString binary = QLatin1String(kGitCommand); const QString binary = QLatin1String(kGitCommand);
m_plugin->outputWindow()->append(formatCommand(binary, arguments)); if (logCommandToWindow)
m_plugin->outputWindow()->append(formatCommand(binary, arguments));
QProcess process; QProcess process;
process.setWorkingDirectory(workingDirectory); process.setWorkingDirectory(workingDirectory);
@@ -456,10 +502,11 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory,
#<tab>modified:<blanks>git.pro #<tab>modified:<blanks>git.pro
\endcode \endcode
*/ */
static bool parseFiles(const QStringList &lines, CommitData *d) static bool parseFiles(const QString &output, CommitData *d)
{ {
enum State { None, CommitFiles, NotUpdatedFiles, UntrackedFiles }; enum State { None, CommitFiles, NotUpdatedFiles, UntrackedFiles };
const QStringList lines = output.split(QLatin1Char('\n'));
const QString branchIndicator = QLatin1String(kBranchIndicatorC); const QString branchIndicator = QLatin1String(kBranchIndicatorC);
const QString commitIndicator = QLatin1String("# Changes to be committed:"); const QString commitIndicator = QLatin1String("# Changes to be committed:");
const QString notUpdatedIndicator = QLatin1String("# Changed but not updated:"); const QString notUpdatedIndicator = QLatin1String("# Changed but not updated:");
@@ -492,10 +539,10 @@ static bool parseFiles(const QStringList &lines, CommitData *d)
const QString fileSpec = line.mid(2).trimmed(); const QString fileSpec = line.mid(2).trimmed();
switch (s) { switch (s) {
case CommitFiles: case CommitFiles:
d->commitFiles.push_back(trimFileSpecification(fileSpec)); d->stagedFiles.push_back(trimFileSpecification(fileSpec));
break; break;
case NotUpdatedFiles: case NotUpdatedFiles:
d->notUpdatedFiles.push_back(trimFileSpecification(fileSpec)); d->unstagedFiles.push_back(trimFileSpecification(fileSpec));
break; break;
case UntrackedFiles: case UntrackedFiles:
d->untrackedFiles.push_back(QLatin1String("untracked: ") + fileSpec); d->untrackedFiles.push_back(QLatin1String("untracked: ") + fileSpec);
@@ -509,7 +556,7 @@ static bool parseFiles(const QStringList &lines, CommitData *d)
} }
} }
} }
return !d->commitFiles.empty() || !d->notUpdatedFiles.empty() || !d->untrackedFiles.empty(); return !d->stagedFiles.empty() || !d->unstagedFiles.empty() || !d->untrackedFiles.empty();
} }
bool GitClient::getCommitData(const QString &workingDirectory, bool GitClient::getCommitData(const QString &workingDirectory,
@@ -525,7 +572,7 @@ bool GitClient::getCommitData(const QString &workingDirectory,
// Find repo // Find repo
const QString repoDirectory = GitClient::findRepositoryForDirectory(workingDirectory); const QString repoDirectory = GitClient::findRepositoryForDirectory(workingDirectory);
if (repoDirectory.isEmpty()) { if (repoDirectory.isEmpty()) {
*errorMessage = tr("Unable to determine the repository for %1.").arg(workingDirectory); *errorMessage = msgRepositoryNotFound(workingDirectory);
return false; return false;
} }
@@ -551,7 +598,7 @@ bool GitClient::getCommitData(const QString &workingDirectory,
case StatusChanged: case StatusChanged:
break; break;
case StatusUnchanged: case StatusUnchanged:
*errorMessage = tr("There are no modified files."); *errorMessage = msgNoChangedFiles();
return false; return false;
case StatusFailed: case StatusFailed:
return false; return false;
@@ -575,9 +622,8 @@ bool GitClient::getCommitData(const QString &workingDirectory,
// # // #
// # list of files... // # list of files...
const QStringList lines = output.split(QLatin1Char('\n')); if (!parseFiles(output, d)) {
if (!parseFiles(lines, d)) { *errorMessage = msgParseFilesFailed();
*errorMessage = tr("Unable to parse the file output.");
return false; return false;
} }
@@ -638,6 +684,129 @@ bool GitClient::addAndCommit(const QString &repositoryDirectory,
return rc; return rc;
} }
static inline bool askWithInformativeText(QWidget *parent,
const QString &title,
const QString &msg,
const QString &inf,
bool defaultValue)
{
QMessageBox msgBox(QMessageBox::Question, title, msg, QMessageBox::Yes|QMessageBox::No, parent);
msgBox.setInformativeText(inf);
msgBox.setDefaultButton(defaultValue ? QMessageBox::Yes : QMessageBox::No);
return msgBox.exec() == QMessageBox::Yes;
}
/* Revert: This function can be called with a file list (to revert single
* files) or a single directory (revert all). Qt Creator currently has only
* 'revert single' in its VCS menus, but the code is prepared to deal with
* reverting a directory pending a sophisticated selection dialog in the
* VCSBase plugin. */
GitClient::RevertResult GitClient::revertI(QStringList files, bool *ptrToIsDirectory, QString *errorMessage)
{
if (Git::Constants::debug)
qDebug() << Q_FUNC_INFO << files;
if (files.empty())
return RevertCanceled;
// Figure out the working directory
const QFileInfo firstFile(files.front());
const bool isDirectory = firstFile.isDir();
if (ptrToIsDirectory)
*ptrToIsDirectory = isDirectory;
const QString workingDirectory = isDirectory ? firstFile.absoluteFilePath() : firstFile.absolutePath();
const QString repoDirectory = GitClient::findRepositoryForDirectory(workingDirectory);
if (repoDirectory.isEmpty()) {
*errorMessage = msgRepositoryNotFound(workingDirectory);
return RevertFailed;
}
// Check for changes
QString output;
switch (gitStatus(repoDirectory, false, &output, errorMessage)) {
case StatusChanged:
break;
case StatusUnchanged:
return RevertUnchanged;
case StatusFailed:
return RevertFailed;
}
CommitData d;
if (!parseFiles(output, &d)) {
*errorMessage = msgParseFilesFailed();
return RevertFailed;
}
// If we are looking at files, make them relative to the repository
// directory to match them in the status output list.
if (!isDirectory) {
const QDir repoDir(repoDirectory);
const QStringList::iterator cend = files.end();
for (QStringList::iterator it = files.begin(); it != cend; ++it)
*it = repoDir.relativeFilePath(*it);
}
// From the status output, determine all modified [un]staged files.
const QString modifiedPattern = QLatin1String("modified: ");
const QStringList allStagedFiles = GitSubmitEditor::statusListToFileList(d.stagedFiles.filter(modifiedPattern));
const QStringList allUnstagedFiles = GitSubmitEditor::statusListToFileList(d.unstagedFiles.filter(modifiedPattern));
// Unless a directory was passed, filter all modified files for the
// argument file list.
QStringList stagedFiles = allStagedFiles;
QStringList unstagedFiles = allUnstagedFiles;
if (!isDirectory) {
const QSet<QString> filesSet = files.toSet();
stagedFiles = allStagedFiles.toSet().intersect(filesSet).toList();
unstagedFiles = allUnstagedFiles.toSet().intersect(filesSet).toList();
}
if (Git::Constants::debug)
qDebug() << Q_FUNC_INFO << d.stagedFiles << d.unstagedFiles << allStagedFiles << allUnstagedFiles << stagedFiles << unstagedFiles;
if (stagedFiles.empty() && unstagedFiles.empty())
return RevertUnchanged;
// Ask to revert (to do: Handle lists with a selection dialog)
const QMessageBox::StandardButton answer
= QMessageBox::question(m_core->mainWindow(),
tr("Revert"),
tr("The file has been changed. Do you want to revert it?"),
QMessageBox::Yes|QMessageBox::No,
QMessageBox::No);
if (answer == QMessageBox::No)
return RevertCanceled;
// Unstage the staged files
if (!stagedFiles.empty() && !synchronousReset(repoDirectory, stagedFiles, errorMessage))
return RevertFailed;
// Finally revert!
if (!synchronousCheckout(repoDirectory, stagedFiles + unstagedFiles, errorMessage))
return RevertFailed;
return RevertOk;
}
void GitClient::revert(const QStringList &files)
{
bool isDirectory;
QString errorMessage;
switch (revertI(files, &isDirectory, &errorMessage)) {
case RevertOk:
case RevertCanceled:
break;
case RevertUnchanged: {
const QString msg = (isDirectory || files.size() > 1) ? msgNoChangedFiles() : tr("The file is not modified.");
m_plugin->outputWindow()->append(msg);
m_plugin->outputWindow()->popup();
}
break;
case RevertFailed:
m_plugin->outputWindow()->append(errorMessage);
m_plugin->outputWindow()->popup();
break;
}
}
void GitClient::pull(const QString &workingDirectory) void GitClient::pull(const QString &workingDirectory)
{ {
executeGit(workingDirectory, QStringList(QLatin1String("pull")), m_plugin->outputWindow(), 0, true); executeGit(workingDirectory, QStringList(QLatin1String("pull")), m_plugin->outputWindow(), 0, true);
@@ -648,6 +817,11 @@ void GitClient::push(const QString &workingDirectory)
executeGit(workingDirectory, QStringList(QLatin1String("push")), m_plugin->outputWindow(), 0, true); executeGit(workingDirectory, QStringList(QLatin1String("push")), m_plugin->outputWindow(), 0, true);
} }
QString GitClient::msgNoChangedFiles()
{
return tr("There are no modified files.");
}
void GitClient::stash(const QString &workingDirectory) void GitClient::stash(const QString &workingDirectory)
{ {
// Check for changes and stash // Check for changes and stash
@@ -657,7 +831,7 @@ void GitClient::stash(const QString &workingDirectory)
executeGit(workingDirectory, QStringList(QLatin1String("stash")), m_plugin->outputWindow(), 0, true); executeGit(workingDirectory, QStringList(QLatin1String("stash")), m_plugin->outputWindow(), 0, true);
break; break;
case StatusUnchanged: case StatusUnchanged:
m_plugin->outputWindow()->append(tr("There are no modified files.")); m_plugin->outputWindow()->append(msgNoChangedFiles());
m_plugin->outputWindow()->popup(); m_plugin->outputWindow()->popup();
break; break;
case StatusFailed: case StatusFailed:
@@ -694,8 +868,8 @@ QString GitClient::readConfig(const QString &workingDirectory, const QStringList
arguments << QLatin1String("config") << configVar; arguments << QLatin1String("config") << configVar;
QByteArray outputText; QByteArray outputText;
if (synchronousGit(workingDirectory, arguments, &outputText)) if (synchronousGit(workingDirectory, arguments, &outputText, 0, false))
return QString::fromLocal8Bit(outputText); return QString::fromLocal8Bit(outputText).remove(QLatin1Char('\r'));
return QString(); return QString();
} }

View File

@@ -90,11 +90,14 @@ public:
void addFile(const QString &workingDirectory, const QString &fileName); void addFile(const QString &workingDirectory, const QString &fileName);
bool synchronousAdd(const QString &workingDirectory, const QStringList &files); bool synchronousAdd(const QString &workingDirectory, const QStringList &files);
bool synchronousReset(const QString &workingDirectory, const QStringList &files); bool synchronousReset(const QString &workingDirectory, const QStringList &files);
bool synchronousReset(const QString &workingDirectory, const QStringList &files, QString *errorMessage);
bool synchronousCheckout(const QString &workingDirectory, const QStringList &files, QString *errorMessage);
void pull(const QString &workingDirectory); void pull(const QString &workingDirectory);
void push(const QString &workingDirectory); void push(const QString &workingDirectory);
void stash(const QString &workingDirectory); void stash(const QString &workingDirectory);
void stashPop(const QString &workingDirectory); void stashPop(const QString &workingDirectory);
void revert(const QStringList &files);
void branchList(const QString &workingDirectory); void branchList(const QString &workingDirectory);
void stashList(const QString &workingDirectory); void stashList(const QString &workingDirectory);
@@ -113,19 +116,21 @@ public:
const QStringList &checkedFiles, const QStringList &checkedFiles,
const QStringList &origCommitFiles); const QStringList &origCommitFiles);
GitSettings settings() const;
void setSettings(const GitSettings &s);
public slots:
void show(const QString &source, const QString &id);
private:
enum StatusResult { StatusChanged, StatusUnchanged, StatusFailed }; enum StatusResult { StatusChanged, StatusUnchanged, StatusFailed };
StatusResult gitStatus(const QString &workingDirectory, StatusResult gitStatus(const QString &workingDirectory,
bool untracked, bool untracked,
QString *output = 0, QString *output = 0,
QString *errorMessage = 0); QString *errorMessage = 0);
GitSettings settings() const;
void setSettings(const GitSettings &s);
static QString msgNoChangedFiles();
public slots:
void show(const QString &source, const QString &id);
private:
VCSBase::VCSBaseEditor *createVCSEditor(const QString &kind, VCSBase::VCSBaseEditor *createVCSEditor(const QString &kind,
QString title, QString title,
const QString &source, const QString &source,
@@ -141,9 +146,13 @@ private:
bool outputToWindow = false); bool outputToWindow = false);
bool synchronousGit(const QString &workingDirectory, bool synchronousGit(const QString &workingDirectory,
const QStringList &arguments, const QStringList &arguments,
QByteArray* outputText = 0, QByteArray* outputText = 0,
QByteArray* errorText = 0); QByteArray* errorText = 0,
bool logCommandToWindow = true);
enum RevertResult { RevertOk, RevertUnchanged, RevertCanceled, RevertFailed };
RevertResult revertI(QStringList files, bool *isDirectory, QString *errorMessage);
const QString m_msgWait; const QString m_msgWait;
GitPlugin *m_plugin; GitPlugin *m_plugin;

View File

@@ -118,7 +118,9 @@ GitPlugin::GitPlugin() :
m_undoFileAction(0), m_undoFileAction(0),
m_undoProjectAction(0), m_undoProjectAction(0),
m_showAction(0), m_showAction(0),
m_addAction(0), m_stageAction(0),
m_unstageAction(0),
m_revertAction(0),
m_commitAction(0), m_commitAction(0),
m_pullAction(0), m_pullAction(0),
m_pushAction(0), m_pushAction(0),
@@ -311,11 +313,23 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *error_message)
connect(m_undoFileAction, SIGNAL(triggered()), this, SLOT(undoFileChanges())); connect(m_undoFileAction, SIGNAL(triggered()), this, SLOT(undoFileChanges()));
gitContainer->addAction(command); gitContainer->addAction(command);
m_addAction = new QAction(tr("Add File"), this); m_stageAction = new QAction(tr("Stage file for commit"), this);
command = actionManager->registerAction(m_addAction, "Git.Add", globalcontext); command = actionManager->registerAction(m_stageAction, "Git.Stage", globalcontext);
command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+A"))); command->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+A")));
command->setAttribute(Core::ICommand::CA_UpdateText); command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_addAction, SIGNAL(triggered()), this, SLOT(addFile())); connect(m_stageAction, SIGNAL(triggered()), this, SLOT(stageFile()));
gitContainer->addAction(command);
m_unstageAction = new QAction(tr("Unstage file from commit"), this);
command = actionManager->registerAction(m_unstageAction, "Git.Unstage", globalcontext);
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_unstageAction, SIGNAL(triggered()), this, SLOT(unstageFile()));
gitContainer->addAction(command);
m_revertAction = new QAction(tr("Revert..."), this);
command = actionManager->registerAction(m_revertAction, "Git.Revert", globalcontext);
command->setAttribute(Core::ICommand::CA_UpdateText);
connect(m_revertAction, SIGNAL(triggered()), this, SLOT(revertFile()));
gitContainer->addAction(command); gitContainer->addAction(command);
gitContainer->addAction(createSeparator(actionManager, globalcontext, QLatin1String("Git.Sep.Project"), this)); gitContainer->addAction(createSeparator(actionManager, globalcontext, QLatin1String("Git.Sep.Project"), this));
@@ -537,14 +551,28 @@ void GitPlugin::undoProjectChanges()
m_gitClient->hardReset(workingDirectory, QString()); m_gitClient->hardReset(workingDirectory, QString());
} }
void GitPlugin::addFile() void GitPlugin::stageFile()
{ {
QFileInfo fileInfo = currentFile(); const QFileInfo fileInfo = currentFile();
QString fileName = fileInfo.fileName(); const QString fileName = fileInfo.fileName();
QString workingDirectory = fileInfo.absolutePath(); const QString workingDirectory = fileInfo.absolutePath();
m_gitClient->addFile(workingDirectory, fileName); m_gitClient->addFile(workingDirectory, fileName);
} }
void GitPlugin::unstageFile()
{
const QFileInfo fileInfo = currentFile();
const QString fileName = fileInfo.fileName();
const QString workingDirectory = fileInfo.absolutePath();
m_gitClient->synchronousReset(workingDirectory, QStringList(fileName));
}
void GitPlugin::revertFile()
{
const QFileInfo fileInfo = currentFile();
m_gitClient->revert(QStringList(fileInfo.absoluteFilePath()));
}
void GitPlugin::startCommit() void GitPlugin::startCommit()
{ {
if (m_changeTmpFile) { if (m_changeTmpFile) {
@@ -570,7 +598,7 @@ void GitPlugin::startCommit()
// Store repository for diff and the original list of // Store repository for diff and the original list of
// files to be able to unstage files the user unchecks // files to be able to unstage files the user unchecks
m_submitRepository = data.panelInfo.repository; m_submitRepository = data.panelInfo.repository;
m_submitOrigCommitFiles = GitSubmitEditor::statusListToFileList(data.commitFiles); m_submitOrigCommitFiles = GitSubmitEditor::statusListToFileList(data.stagedFiles);
if (Git::Constants::debug) if (Git::Constants::debug)
qDebug() << Q_FUNC_INFO << data << commitTemplate; qDebug() << Q_FUNC_INFO << data << commitTemplate;
@@ -602,7 +630,7 @@ Core::IEditor *GitPlugin::openSubmitEditor(const QString &fileName, const Commit
Q_ASSERT(submitEditor); Q_ASSERT(submitEditor);
// The actions are for some reason enabled by the context switching // The actions are for some reason enabled by the context switching
// mechanism. Disable them correctly. // mechanism. Disable them correctly.
m_submitCurrentAction->setEnabled(!cd.commitFiles.empty()); m_submitCurrentAction->setEnabled(!cd.stagedFiles.empty());
m_diffSelectedFilesAction->setEnabled(false); m_diffSelectedFilesAction->setEnabled(false);
m_undoAction->setEnabled(false); m_undoAction->setEnabled(false);
m_redoAction->setEnabled(false); m_redoAction->setEnabled(false);
@@ -722,7 +750,9 @@ void GitPlugin::updateActions()
m_logAction->setText(tr("Log %1").arg(fileName)); m_logAction->setText(tr("Log %1").arg(fileName));
m_blameAction->setText(tr("Blame %1").arg(fileName)); m_blameAction->setText(tr("Blame %1").arg(fileName));
m_undoFileAction->setText(tr("Undo changes for %1").arg(fileName)); m_undoFileAction->setText(tr("Undo changes for %1").arg(fileName));
m_addAction->setText(tr("Add %1").arg(fileName)); m_stageAction->setText(tr("Stage %1 for commit").arg(fileName));
m_unstageAction->setText(tr("Unstage %1 from commit").arg(fileName));
m_revertAction->setText(tr("Revert %1...").arg(fileName));
if (repository.isEmpty()) { if (repository.isEmpty()) {
// If the file is not in a repository, the corresponding project will // If the file is not in a repository, the corresponding project will
// be neither and we can disable everything and return // be neither and we can disable everything and return
@@ -731,7 +761,9 @@ void GitPlugin::updateActions()
m_logAction->setEnabled(false); m_logAction->setEnabled(false);
m_blameAction->setEnabled(false); m_blameAction->setEnabled(false);
m_undoFileAction->setEnabled(false); m_undoFileAction->setEnabled(false);
m_addAction->setEnabled(false); m_stageAction->setEnabled(false);
m_unstageAction->setEnabled(false);
m_revertAction->setEnabled(false);
m_diffProjectAction->setEnabled(false); m_diffProjectAction->setEnabled(false);
m_diffProjectAction->setText(tr("Diff Project")); m_diffProjectAction->setText(tr("Diff Project"));
m_statusProjectAction->setText(tr("Status Project")); m_statusProjectAction->setText(tr("Status Project"));
@@ -747,7 +779,9 @@ void GitPlugin::updateActions()
m_logAction->setEnabled(true); m_logAction->setEnabled(true);
m_blameAction->setEnabled(true); m_blameAction->setEnabled(true);
m_undoFileAction->setEnabled(true); m_undoFileAction->setEnabled(true);
m_addAction->setEnabled(true); m_stageAction->setEnabled(true);
m_unstageAction->setEnabled(true);
m_revertAction->setEnabled(true);
} }
if (m_projectExplorer && m_projectExplorer->currentNode() if (m_projectExplorer && m_projectExplorer->currentNode()

View File

@@ -116,7 +116,9 @@ private slots:
void logProject(); void logProject();
void undoFileChanges(); void undoFileChanges();
void undoProjectChanges(); void undoProjectChanges();
void addFile(); void stageFile();
void unstageFile();
void revertFile();
void showCommit(); void showCommit();
void startCommit(); void startCommit();
@@ -144,7 +146,9 @@ private:
QAction *m_undoFileAction; QAction *m_undoFileAction;
QAction *m_undoProjectAction; QAction *m_undoProjectAction;
QAction *m_showAction; QAction *m_showAction;
QAction *m_addAction; QAction *m_stageAction;
QAction *m_unstageAction;
QAction *m_revertAction;
QAction *m_commitAction; QAction *m_commitAction;
QAction *m_pullAction; QAction *m_pullAction;
QAction *m_pushAction; QAction *m_pushAction;

View File

@@ -67,9 +67,9 @@ void GitSubmitEditor::setCommitData(const CommitData &d)
submitEditorWidget()->setPanelData(d.panelData); submitEditorWidget()->setPanelData(d.panelData);
submitEditorWidget()->setPanelInfo(d.panelInfo); submitEditorWidget()->setPanelInfo(d.panelInfo);
addFiles(d.commitFiles, true, true); addFiles(d.stagedFiles, true, true);
// Not Updated: Initially unchecked // Not Updated: Initially unchecked
addFiles(d.notUpdatedFiles, false, true); addFiles(d.unstagedFiles, false, true);
addFiles(d.untrackedFiles, false, true); addFiles(d.untrackedFiles, false, true);
} }

View File

@@ -16,8 +16,8 @@ HEADERS += helpplugin.h \
searchwidget.h \ searchwidget.h \
helpfindsupport.h \ helpfindsupport.h \
help_global.h \ help_global.h \
helpindexfilter.h \ helpindexfilter.h
indexwindow.h
SOURCES += helpplugin.cpp \ SOURCES += helpplugin.cpp \
docsettingspage.cpp \ docsettingspage.cpp \
filtersettingspage.cpp \ filtersettingspage.cpp \
@@ -26,6 +26,7 @@ SOURCES += helpplugin.cpp \
searchwidget.cpp \ searchwidget.cpp \
helpfindsupport.cpp \ helpfindsupport.cpp \
helpindexfilter.cpp helpindexfilter.cpp
FORMS += docsettingspage.ui \ FORMS += docsettingspage.ui \
filtersettingspage.ui filtersettingspage.ui
RESOURCES += help.qrc RESOURCES += help.qrc

View File

@@ -405,17 +405,17 @@ void PerforcePlugin::extensionsInitialized()
void PerforcePlugin::openCurrentFile() void PerforcePlugin::openCurrentFile()
{ {
runP4Cmd(QStringList() << QLatin1String("edit") << currentFileName(), QStringList(), true); vcsOpen(currentFileName());
} }
void PerforcePlugin::addCurrentFile() void PerforcePlugin::addCurrentFile()
{ {
runP4Cmd(QStringList() << QLatin1String("add") << currentFileName(), QStringList(), true); vcsAdd(currentFileName());
} }
void PerforcePlugin::deleteCurrentFile() void PerforcePlugin::deleteCurrentFile()
{ {
runP4Cmd(QStringList() << QLatin1String("delete") << currentFileName(), QStringList(), true); vcsDelete(currentFileName());
} }
void PerforcePlugin::revertCurrentFile() void PerforcePlugin::revertCurrentFile()
@@ -426,7 +426,7 @@ void PerforcePlugin::revertCurrentFile()
QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(m_coreInstance, fileName); QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(m_coreInstance, fileName);
QStringList args; QStringList args;
args << QLatin1String("diff") << QLatin1String("-sa"); args << QLatin1String("diff") << QLatin1String("-sa");
PerforceResponse result = runP4Cmd(args, QStringList(), false, true, codec); PerforceResponse result = runP4Cmd(args, QStringList(), CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
if (result.error) if (result.error)
return; return;
@@ -444,7 +444,7 @@ void PerforcePlugin::revertCurrentFile()
foreach (Core::IFile *file, files) { foreach (Core::IFile *file, files) {
fm->blockFileChange(file); fm->blockFileChange(file);
} }
PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(), true); PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(), CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
Core::IFile::ReloadBehavior tempBehavior = Core::IFile::ReloadBehavior tempBehavior =
Core::IFile::ReloadAll; Core::IFile::ReloadAll;
foreach (Core::IFile *file, files) { foreach (Core::IFile *file, files) {
@@ -489,7 +489,7 @@ void PerforcePlugin::printOpenedFileList()
Core::IEditor *e = m_coreInstance->editorManager()->currentEditor(); Core::IEditor *e = m_coreInstance->editorManager()->currentEditor();
if (e) if (e)
e->widget()->setFocus(); e->widget()->setFocus();
PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("opened"), QStringList(), true); PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("opened"), QStringList(), CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
} }
#ifdef USE_P4_API #ifdef USE_P4_API
@@ -522,7 +522,8 @@ void PerforcePlugin::submit()
return; return;
} }
PerforceResponse result = runP4Cmd(QStringList()<< QLatin1String("change") << QLatin1String("-o"), QStringList(), false); PerforceResponse result = runP4Cmd(QStringList()<< QLatin1String("change") << QLatin1String("-o"), QStringList(),
CommandToWindow|StdErrToWindow|ErrorToWindow);
if (result.error) { if (result.error) {
delete m_changeTmpFile; delete m_changeTmpFile;
m_changeTmpFile = 0; m_changeTmpFile = 0;
@@ -550,7 +551,8 @@ void PerforcePlugin::submit()
foreach (const QString &f, files) foreach (const QString &f, files)
nativeFiles << QDir::toNativeSeparators(f); nativeFiles << QDir::toNativeSeparators(f);
PerforceResponse result2 = runP4Cmd(QStringList(QLatin1String("fstat")), nativeFiles, false); PerforceResponse result2 = runP4Cmd(QStringList(QLatin1String("fstat")), nativeFiles,
CommandToWindow|StdErrToWindow|ErrorToWindow);
if (result2.error) { if (result2.error) {
delete m_changeTmpFile; delete m_changeTmpFile;
m_changeTmpFile = 0; m_changeTmpFile = 0;
@@ -597,8 +599,10 @@ void PerforcePlugin::printPendingChanges()
PendingChangesDialog dia(pendingChangesData(), m_coreInstance->mainWindow()); PendingChangesDialog dia(pendingChangesData(), m_coreInstance->mainWindow());
qApp->restoreOverrideCursor(); qApp->restoreOverrideCursor();
if (dia.exec() == QDialog::Accepted) { if (dia.exec() == QDialog::Accepted) {
int i = dia.changeNumber(); const int i = dia.changeNumber();
PerforceResponse result = runP4Cmd(QStringList()<<"submit"<<"-c"<<QString::number(i), QStringList(), true); QStringList args(QLatin1String("submit"));
args << QLatin1String("-c") << QString::number(i);
runP4Cmd(args, QStringList(), CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
} }
} }
@@ -628,7 +632,8 @@ void PerforcePlugin::annotate(const QString &fileName)
QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(m_coreInstance, fileName); QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(m_coreInstance, fileName);
QStringList args; QStringList args;
args << QLatin1String("annotate") << QLatin1String("-cqi") << fileName; args << QLatin1String("annotate") << QLatin1String("-cqi") << fileName;
const PerforceResponse result = runP4Cmd(args, QStringList(), false, true, codec); const PerforceResponse result = runP4Cmd(args, QStringList(),
CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
if (!result.error) { if (!result.error) {
const QFileInfo fi(fileName); const QFileInfo fi(fileName);
showOutputInEditor(tr("p4 annotate %1").arg(fi.fileName()), result.stdOut, VCSBase::AnnotateOutput, codec); showOutputInEditor(tr("p4 annotate %1").arg(fi.fileName()), result.stdOut, VCSBase::AnnotateOutput, codec);
@@ -654,7 +659,8 @@ void PerforcePlugin::filelog(const QString &fileName)
QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(m_coreInstance, fileName); QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(m_coreInstance, fileName);
QStringList args; QStringList args;
args << QLatin1String("filelog") << QLatin1String("-li") << fileName; args << QLatin1String("filelog") << QLatin1String("-li") << fileName;
const PerforceResponse result = runP4Cmd(args, QStringList(), false, true, codec); const PerforceResponse result = runP4Cmd(args, QStringList(),
CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
if (!result.error) { if (!result.error) {
const QFileInfo fi(fileName); const QFileInfo fi(fileName);
showOutputInEditor(tr("p4 filelog %1").arg(fi.fileName()), result.stdOut, VCSBase::LogOutput, codec); showOutputInEditor(tr("p4 filelog %1").arg(fi.fileName()), result.stdOut, VCSBase::LogOutput, codec);
@@ -718,18 +724,19 @@ bool PerforcePlugin::managesDirectory(const QString &directory) const
QStringList args; QStringList args;
args << QLatin1String("fstat") << QLatin1String("-m1") << p4Path; args << QLatin1String("fstat") << QLatin1String("-m1") << p4Path;
const PerforceResponse result = runP4Cmd(args, QStringList(), false, false); const PerforceResponse result = runP4Cmd(args, QStringList(), 0u);
return result.stdOut.contains("depotFile") || result.stdErr.contains("... - no such file(s)"); return result.stdOut.contains("depotFile") || result.stdErr.contains("... - no such file(s)");
} }
QString PerforcePlugin::findTopLevelForDirectory(const QString & /* dir */) const QString PerforcePlugin::findTopLevelForDirectory(const QString & /* dir */) const
{ {
// First check with p4 client -o // First check with p4 client -o
PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("client") << QLatin1String("-o"), QStringList(), false, false); PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("client") << QLatin1String("-o"), QStringList(), 0u);
if (result.error) if (result.error)
return QString::null; return QString::null;
QRegExp regExp(QLatin1String("(\\n|\\r\\n|\\r)Root:\\s*(.*)(\\n|\\r\\n|\\r)")); QRegExp regExp(QLatin1String("(\\n|\\r\\n|\\r)Root:\\s*(.*)(\\n|\\r\\n|\\r)"));
Q_ASSERT(regExp.isValid());
regExp.setMinimal(true); regExp.setMinimal(true);
if (regExp.indexIn(result.stdOut) != -1) { if (regExp.indexIn(result.stdOut) != -1) {
QString file = regExp.cap(2).trimmed(); QString file = regExp.cap(2).trimmed();
@@ -741,20 +748,24 @@ QString PerforcePlugin::findTopLevelForDirectory(const QString & /* dir */) cons
bool PerforcePlugin::vcsOpen(const QString &fileName) bool PerforcePlugin::vcsOpen(const QString &fileName)
{ {
PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("edit") << QDir::toNativeSeparators(fileName), QStringList(), true); PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("edit") << QDir::toNativeSeparators(fileName), QStringList(),
CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
return !result.error; return !result.error;
} }
bool PerforcePlugin::vcsAdd(const QString &fileName) bool PerforcePlugin::vcsAdd(const QString &fileName)
{ {
PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("add") << fileName, QStringList(), true); PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("add") << fileName, QStringList(),
CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
return !result.error; return !result.error;
} }
bool PerforcePlugin::vcsDelete(const QString &fileName) bool PerforcePlugin::vcsDelete(const QString &fileName)
{ {
PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(), true); PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("revert") << fileName, QStringList(),
PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("delete") << fileName, QStringList(), true); CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
PerforceResponse result2 = runP4Cmd(QStringList() << QLatin1String("delete") << fileName, QStringList(),
CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow);
// TODO need to carefully parse the actual messages from perforce // TODO need to carefully parse the actual messages from perforce
// or do a fstat before to decide what to do // or do a fstat before to decide what to do
@@ -767,8 +778,7 @@ bool PerforcePlugin::vcsDelete(const QString &fileName)
PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args, PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
const QStringList &extraArgs, const QStringList &extraArgs,
bool showStdOutInOutputWindow, unsigned logFlags,
bool showStdErrInOutputWindow,
QTextCodec *outputCodec) const QTextCodec *outputCodec) const
{ {
if (Perforce::Constants::debug) if (Perforce::Constants::debug)
@@ -801,12 +811,14 @@ PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
} }
actualArgs << args; actualArgs << args;
response.command = m_settings.p4Command; if (logFlags & CommandToWindow) {
response.command += blank; QString command = m_settings.p4Command;
response.command += actualArgs.join(QString(blank)); command += blank;
const QString timeStamp = QTime::currentTime().toString(QLatin1String("HH:mm")); command += actualArgs.join(QString(blank));
const QString outputText = tr("%1 Executing: %2\n").arg(timeStamp, response.command); const QString timeStamp = QTime::currentTime().toString(QLatin1String("HH:mm"));
showOutput(outputText, false); const QString outputText = tr("%1 Executing: %2\n").arg(timeStamp, command);
showOutput(outputText, false);
}
// Run, connect stderr to the output window // Run, connect stderr to the output window
Core::Utils::SynchronousProcess process; Core::Utils::SynchronousProcess process;
@@ -815,13 +827,13 @@ PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
process.setEnvironment(environment()); process.setEnvironment(environment());
// connect stderr to the output window if desired // connect stderr to the output window if desired
if (showStdErrInOutputWindow) { if (logFlags & StdErrToWindow) {
process.setStdErrBufferedSignalsEnabled(true); process.setStdErrBufferedSignalsEnabled(true);
connect(&process, SIGNAL(stdErrBuffered(QString,bool)), m_perforceOutputWindow, SLOT(append(QString,bool))); connect(&process, SIGNAL(stdErrBuffered(QString,bool)), m_perforceOutputWindow, SLOT(append(QString,bool)));
} }
// connect stdout to the output window if desired // connect stdout to the output window if desired
if (showStdOutInOutputWindow) { if (logFlags & StdOutToWindow) {
process.setStdOutBufferedSignalsEnabled(true); process.setStdOutBufferedSignalsEnabled(true);
connect(&process, SIGNAL(stdOutBuffered(QString,bool)), m_perforceOutputWindow, SLOT(append(QString,bool))); connect(&process, SIGNAL(stdOutBuffered(QString,bool)), m_perforceOutputWindow, SLOT(append(QString,bool)));
} }
@@ -847,13 +859,15 @@ PerforceResponse PerforcePlugin::runP4Cmd(const QStringList &args,
response.message = tr("Could not start perforce '%1'. Please check your settings in the preferences.").arg(m_settings.p4Command); response.message = tr("Could not start perforce '%1'. Please check your settings in the preferences.").arg(m_settings.p4Command);
break; break;
case Core::Utils::SynchronousProcessResponse::Hang: case Core::Utils::SynchronousProcessResponse::Hang:
response.message = tr("Subversion did not respond within timeout limit (%1 ms).").arg(p4Timeout ); response.message = tr("Perforce did not respond within timeout limit (%1 ms).").arg(p4Timeout );
break; break;
} }
if (response.error) if (response.error) {
m_perforceOutputWindow->append(response.message, true); if (Perforce::Constants::debug)
qDebug() << response.message;
if (logFlags & ErrorToWindow)
m_perforceOutputWindow->append(response.message, true);
}
return response; return response;
} }
@@ -923,7 +937,7 @@ void PerforcePlugin::p4Diff(const QStringList &files, QString diffname)
} }
} }
const PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("diff") << QLatin1String("-du"), files, false, codec); const PerforceResponse result = runP4Cmd(QStringList() << QLatin1String("diff") << QLatin1String("-du"), files, CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
if (result.error) if (result.error)
return; return;
@@ -948,7 +962,7 @@ void PerforcePlugin::describe(const QString & source, const QString &n)
QTextCodec *codec = source.isEmpty() ? static_cast<QTextCodec *>(0) : VCSBase::VCSBaseEditor::getCodec(m_coreInstance, source); QTextCodec *codec = source.isEmpty() ? static_cast<QTextCodec *>(0) : VCSBase::VCSBaseEditor::getCodec(m_coreInstance, source);
QStringList args; QStringList args;
args << QLatin1String("describe") << QLatin1String("-du") << n; args << QLatin1String("describe") << QLatin1String("-du") << n;
const PerforceResponse result = runP4Cmd(args, QStringList(), codec); const PerforceResponse result = runP4Cmd(args, QStringList(), CommandToWindow|StdErrToWindow|ErrorToWindow, codec);
if (!result.error) if (!result.error)
showOutputInEditor(tr("p4 describe %1").arg(n), result.stdOut, VCSBase::DiffOutput, codec); showOutputInEditor(tr("p4 describe %1").arg(n), result.stdOut, VCSBase::DiffOutput, codec);
} }

View File

@@ -86,7 +86,6 @@ private:
struct PerforceResponse struct PerforceResponse
{ {
bool error; bool error;
QString command;
QString stdOut; QString stdOut;
QString stdErr; QString stdErr;
QString message; QString message;
@@ -161,12 +160,15 @@ private:
Core::IEditor *showOutputInEditor(const QString& title, const QString output, Core::IEditor *showOutputInEditor(const QString& title, const QString output,
int editorType, int editorType,
QTextCodec *codec = 0); QTextCodec *codec = 0);
// Verbosity flags for runP4Cmd.
enum RunLogFlags { CommandToWindow = 0x1, StdOutToWindow = 0x2, StdErrToWindow = 0x4, ErrorToWindow = 0x8 };
// args are passed as command line arguments // args are passed as command line arguments
// extra args via a tempfile and the option -x "temp-filename" // extra args via a tempfile and the option -x "temp-filename"
PerforceResponse runP4Cmd(const QStringList &args, PerforceResponse runP4Cmd(const QStringList &args,
const QStringList &extraArgs = QStringList(), const QStringList &extraArgs = QStringList(),
bool showStdOutInOutputWindow = false, unsigned logFlags = CommandToWindow|StdErrToWindow|ErrorToWindow,
bool showStdErrInOutputWindow = true,
QTextCodec *outputCodec = 0) const; QTextCodec *outputCodec = 0) const;
void openFiles(const QStringList &files); void openFiles(const QStringList &files);

View File

@@ -104,8 +104,9 @@
<widget class="QLabel" name="filesLabel"> <widget class="QLabel" name="filesLabel">
<property name="text"> <property name="text">
<string>The following files will be added: <string>The following files will be added:
f1
f2
</string> </string>
</property> </property>
<property name="textInteractionFlags"> <property name="textInteractionFlags">

View File

@@ -35,6 +35,7 @@
#include "consoleappwizard.h" #include "consoleappwizard.h"
#include "modulespage.h" #include "modulespage.h"
#include <QtCore/QDebug>
#include <utils/projectintropage.h> #include <utils/projectintropage.h>
namespace Qt4ProjectManager { namespace Qt4ProjectManager {
@@ -51,13 +52,11 @@ ConsoleAppWizardDialog::ConsoleAppWizardDialog(const QString &templateName,
setWindowIcon(icon); setWindowIcon(icon);
setWindowTitle(templateName); setWindowTitle(templateName);
Core::BaseFileWizard::setupWizard(this); Core::BaseFileWizard::setupWizard(this);
setOptions(QWizard::IndependentPages | QWizard::HaveNextButtonOnLastPage);
m_introPage->setDescription(tr("This wizard generates a Qt4 console application " m_introPage->setDescription(tr("This wizard generates a Qt4 console application "
"project. The application derives from QCoreApplication and does not " "project. The application derives from QCoreApplication and does not "
"present a GUI. You can press 'Finish' at any point in time.")); "present a GUI. You can press 'Finish' at any point in time."));
m_introPage->setFinalPage(true);
addPage(m_introPage); addPage(m_introPage);
m_modulesPage->setModuleSelected(QLatin1String("core")); m_modulesPage->setModuleSelected(QLatin1String("core"));

View File

@@ -63,7 +63,6 @@ GuiAppWizardDialog::GuiAppWizardDialog(const QString &templateName,
setWindowIcon(icon); setWindowIcon(icon);
setWindowTitle(templateName); setWindowTitle(templateName);
Core::BaseFileWizard::setupWizard(this); Core::BaseFileWizard::setupWizard(this);
setOptions(QWizard::IndependentPages);
m_introPage->setDescription(tr("This wizard generates a Qt4 GUI application " m_introPage->setDescription(tr("This wizard generates a Qt4 GUI application "
"project. The application derives by default from QApplication " "project. The application derives by default from QApplication "

View File

@@ -79,6 +79,7 @@
#include <QtGui/QToolBar> #include <QtGui/QToolBar>
#include <QtGui/QToolTip> #include <QtGui/QToolTip>
#include <QtGui/QInputDialog> #include <QtGui/QInputDialog>
#include <QtGui/QMenu>
using namespace TextEditor; using namespace TextEditor;
using namespace TextEditor::Internal; using namespace TextEditor::Internal;
@@ -487,10 +488,6 @@ ITextEditable *BaseTextEditor::editableInterface() const
d->m_editable, SIGNAL(contentsChanged())); d->m_editable, SIGNAL(contentsChanged()));
connect(this, SIGNAL(changed()), connect(this, SIGNAL(changed()),
d->m_editable, SIGNAL(changed())); d->m_editable, SIGNAL(changed()));
connect(this,
SIGNAL(markRequested(TextEditor::ITextEditor *, int)),
d->m_editable,
SIGNAL(markRequested(TextEditor::ITextEditor *, int)));
} }
return d->m_editable; return d->m_editable;
} }
@@ -501,7 +498,8 @@ void BaseTextEditor::currentEditorChanged(Core::IEditor *editor)
if (editor == d->m_editable) { if (editor == d->m_editable) {
if (d->m_document->hasDecodingError()) { if (d->m_document->hasDecodingError()) {
Core::EditorManager::instance()->showEditorInfoBar(QLatin1String(Constants::SELECT_ENCODING), Core::EditorManager::instance()->showEditorInfoBar(QLatin1String(Constants::SELECT_ENCODING),
tr("<b>Error:</b> Could not decode \"%1\" with \"%2\"-encoding. Editing not possible.").arg(displayName()).arg(QString::fromLatin1(d->m_document->codec()->name())), tr("<b>Error:</b> Could not decode \"%1\" with \"%2\"-encoding. Editing not possible.")
.arg(displayName()).arg(QString::fromLatin1(d->m_document->codec()->name())),
tr("Select Encoding"), tr("Select Encoding"),
this, SLOT(selectEncoding())); this, SLOT(selectEncoding()));
} }
@@ -531,7 +529,6 @@ void BaseTextEditor::selectEncoding()
} }
} }
void DocumentMarker::updateMark(ITextMark *mark) void DocumentMarker::updateMark(ITextMark *mark)
{ {
TextEditDocumentLayout *documentLayout = qobject_cast<TextEditDocumentLayout*>(document->documentLayout()); TextEditDocumentLayout *documentLayout = qobject_cast<TextEditDocumentLayout*>(document->documentLayout());
@@ -598,8 +595,79 @@ void BaseTextEditor::slotSelectionChanged()
viewport()->update(); viewport()->update();
if (!d->m_inBlockSelectionMode) if (!d->m_inBlockSelectionMode)
d->m_blockSelectionExtraX = 0; d->m_blockSelectionExtraX = 0;
if (!d->m_selectBlockAnchor.isNull() && !textCursor().hasSelection())
d->m_selectBlockAnchor = QTextCursor();
} }
void BaseTextEditor::gotoBlockStart()
{
QTextCursor cursor = textCursor();
if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, false))
setTextCursor(cursor);
}
void BaseTextEditor::gotoBlockEnd()
{
QTextCursor cursor = textCursor();
if (TextBlockUserData::findNextClosingParenthesis(&cursor, false))
setTextCursor(cursor);
}
void BaseTextEditor::gotoBlockStartWithSelection()
{
QTextCursor cursor = textCursor();
if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, true))
setTextCursor(cursor);
}
void BaseTextEditor::gotoBlockEndWithSelection()
{
QTextCursor cursor = textCursor();
if (TextBlockUserData::findNextClosingParenthesis(&cursor, true))
setTextCursor(cursor);
}
void BaseTextEditor::selectBlockUp()
{
QTextCursor cursor = textCursor();
if (!cursor.hasSelection())
d->m_selectBlockAnchor = cursor;
else
cursor.setPosition(cursor.selectionStart());
if (!TextBlockUserData::findPreviousOpenParenthesis(&cursor, false))
return;
if (!TextBlockUserData::findNextClosingParenthesis(&cursor, true))
return;
setTextCursor(cursor);
}
void BaseTextEditor::selectBlockDown()
{
QTextCursor tc = textCursor();
QTextCursor cursor = d->m_selectBlockAnchor;
if (!tc.hasSelection() || cursor.isNull())
return;
tc.setPosition(tc.selectionStart());
forever {
QTextCursor ahead = cursor;
if (!TextBlockUserData::findPreviousOpenParenthesis(&ahead, false))
break;
if (ahead.position() <= tc.position())
break;
cursor = ahead;
}
if ( cursor != d->m_selectBlockAnchor)
TextBlockUserData::findNextClosingParenthesis(&cursor, true);
setTextCursor(cursor);
}
void BaseTextEditor::keyPressEvent(QKeyEvent *e) void BaseTextEditor::keyPressEvent(QKeyEvent *e)
{ {
@@ -633,6 +701,11 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
e->accept(); e->accept();
return; return;
} }
} else if (e == QKeySequence::Paste) {
if (!ro) {
d->removeBlockSelection();
// continue
}
} }
} }
@@ -693,6 +766,8 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
break; break;
case Qt::Key_Home: case Qt::Key_Home:
if (!(e == QKeySequence::MoveToStartOfDocument) && !(e == QKeySequence::SelectStartOfDocument)) { if (!(e == QKeySequence::MoveToStartOfDocument) && !(e == QKeySequence::SelectStartOfDocument)) {
if ((e->modifiers() & (Qt::AltModifier | Qt::ShiftModifier)) == (Qt::AltModifier | Qt::ShiftModifier))
d->m_lastEventWasBlockSelectionEvent = true;
handleHomeKey(e->modifiers() & Qt::ShiftModifier); handleHomeKey(e->modifiers() & Qt::ShiftModifier);
e->accept(); e->accept();
return; return;
@@ -708,6 +783,7 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
return; return;
} }
// fall through // fall through
case Qt::Key_End:
case Qt::Key_Right: case Qt::Key_Right:
case Qt::Key_Left: case Qt::Key_Left:
#ifndef Q_OS_MAC #ifndef Q_OS_MAC
@@ -795,6 +871,15 @@ skip_event:
delete e; delete e;
} }
void BaseTextEditor::setTextCursor(const QTextCursor &cursor)
{
// workaround for QTextControl bug
bool selectionChange = cursor.hasSelection() || textCursor().hasSelection();
QPlainTextEdit::setTextCursor(cursor);
if (selectionChange)
slotSelectionChanged();
}
void BaseTextEditor::gotoLine(int line, int column) void BaseTextEditor::gotoLine(int line, int column)
{ {
const int blockNumber = line - 1; const int blockNumber = line - 1;
@@ -2343,6 +2428,12 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e)
} else { } else {
d->extraAreaToggleMarkBlockNumber = cursor.blockNumber(); d->extraAreaToggleMarkBlockNumber = cursor.blockNumber();
} }
} else if (e->button() == Qt::RightButton) {
QMenu * contextMenu = new QMenu(this);
emit d->m_editable->markContextMenuRequested(editableInterface(), cursor.blockNumber(), contextMenu);
if (!contextMenu->isEmpty())
contextMenu->exec(e->globalPos());
delete contextMenu;
} }
} else if (d->extraAreaSelectionAnchorBlockNumber >= 0) { } else if (d->extraAreaSelectionAnchorBlockNumber >= 0) {
QTextCursor selection = cursor; QTextCursor selection = cursor;
@@ -2377,7 +2468,7 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e)
d->extraAreaToggleMarkBlockNumber = -1; d->extraAreaToggleMarkBlockNumber = -1;
if (cursor.blockNumber() == n) { if (cursor.blockNumber() == n) {
int line = n + 1; int line = n + 1;
emit markRequested(editableInterface(), line); emit d->m_editable->markRequested(editableInterface(), line);
} }
} }
} }
@@ -2386,6 +2477,9 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e)
void BaseTextEditor::slotCursorPositionChanged() void BaseTextEditor::slotCursorPositionChanged()
{ {
QList<QTextEdit::ExtraSelection> extraSelections; QList<QTextEdit::ExtraSelection> extraSelections;
setExtraSelections(ParenthesesMatchingSelection, extraSelections); // clear
if (d->m_parenthesesMatchingEnabled)
d->m_parenthesesMatchingTimer->start(50);
if (d->m_highlightCurrentLine) { if (d->m_highlightCurrentLine) {
QTextEdit::ExtraSelection sel; QTextEdit::ExtraSelection sel;
@@ -2396,11 +2490,7 @@ void BaseTextEditor::slotCursorPositionChanged()
extraSelections.append(sel); extraSelections.append(sel);
} }
if (d->m_parenthesesMatchingEnabled) setExtraSelections(CurrentLineSelection, extraSelections);
d->m_parenthesesMatchingTimer->start(50);
d->m_extraSelections = extraSelections;
setExtraSelections(d->m_extraSelections + d->m_extraExtraSelections);
} }
QTextBlock TextBlockUserData::testCollapse(const QTextBlock& block) QTextBlock TextBlockUserData::testCollapse(const QTextBlock& block)
@@ -2908,6 +2998,61 @@ TextBlockUserData::MatchType TextBlockUserData::checkClosedParenthesis(QTextCurs
} }
} }
bool TextBlockUserData::findPreviousOpenParenthesis(QTextCursor *cursor, bool select)
{
QTextBlock block = cursor->block();
int position = cursor->position();
int ignore = 0;
while (block.isValid()) {
Parentheses parenList = TextEditDocumentLayout::parentheses(block);
if (!parenList.isEmpty()) {
for (int i = parenList.count()-1; i >= 0; --i) {
Parenthesis paren = parenList.at(i);
if (block == cursor->block() && position - block.position() <= paren.pos + 1)
continue;
if (paren.type == Parenthesis::Closed) {
++ignore;
} else if (ignore > 0) {
--ignore;
} else {
cursor->setPosition(block.position() + paren.pos, select ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
return true;
}
}
}
block = block.previous();
}
return false;
}
bool TextBlockUserData::findNextClosingParenthesis(QTextCursor *cursor, bool select)
{
QTextBlock block = cursor->block();
int position = cursor->position();
int ignore = 0;
while (block.isValid()) {
Parentheses parenList = TextEditDocumentLayout::parentheses(block);
if (!parenList.isEmpty()) {
for (int i = 0; i < parenList.count(); ++i) {
Parenthesis paren = parenList.at(i);
if (block == cursor->block() && position - block.position() >= paren.pos)
continue;
if (paren.type == Parenthesis::Opened) {
++ignore;
} else if (ignore > 0) {
--ignore;
} else {
cursor->setPosition(block.position() + paren.pos+1, select ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
return true;
}
}
}
block = block.next();
}
return false;
}
TextBlockUserData::MatchType TextBlockUserData::matchCursorBackward(QTextCursor *cursor) TextBlockUserData::MatchType TextBlockUserData::matchCursorBackward(QTextCursor *cursor)
{ {
cursor->clearSelection(); cursor->clearSelection();
@@ -2987,7 +3132,7 @@ void BaseTextEditor::_q_matchParentheses()
if (backwardMatchType == TextBlockUserData::NoMatch && forwardMatchType == TextBlockUserData::NoMatch) if (backwardMatchType == TextBlockUserData::NoMatch && forwardMatchType == TextBlockUserData::NoMatch)
return; return;
QList<QTextEdit::ExtraSelection> extraSelections = d->m_extraSelections; QList<QTextEdit::ExtraSelection> extraSelections;
if (backwardMatch.hasSelection()) { if (backwardMatch.hasSelection()) {
QTextEdit::ExtraSelection sel; QTextEdit::ExtraSelection sel;
@@ -3040,8 +3185,7 @@ void BaseTextEditor::_q_matchParentheses()
} }
extraSelections.append(sel); extraSelections.append(sel);
} }
d->m_extraSelections = extraSelections; setExtraSelections(ParenthesesMatchingSelection, extraSelections);
setExtraSelections(d->m_extraSelections + d->m_extraExtraSelections);
} }
void BaseTextEditor::setActionHack(QObject *hack) void BaseTextEditor::setActionHack(QObject *hack)
@@ -3088,15 +3232,21 @@ void BaseTextEditor::deleteLine()
cut(); cut();
} }
void BaseTextEditor::setExtraExtraSelections(const QList<QTextEdit::ExtraSelection> &selections) void BaseTextEditor::setExtraSelections(ExtraSelectionKind kind, const QList<QTextEdit::ExtraSelection> &selections)
{ {
d->m_extraExtraSelections = selections; if (selections.isEmpty() && d->m_extraSelections[kind].isEmpty())
setExtraSelections(d->m_extraSelections + d->m_extraExtraSelections); return;
d->m_extraSelections[kind] = selections;
QList<QTextEdit::ExtraSelection> all;
for (int i = 0; i < NExtraSelectionKinds; ++i)
all += d->m_extraSelections[i];
QPlainTextEdit::setExtraSelections(all);
} }
QList<QTextEdit::ExtraSelection> BaseTextEditor::extraExtraSelections() const QList<QTextEdit::ExtraSelection> BaseTextEditor::extraSelections(ExtraSelectionKind kind) const
{ {
return d->m_extraExtraSelections; return d->m_extraSelections[kind];
} }
@@ -3152,13 +3302,16 @@ void BaseTextEditor::collapse()
TextEditDocumentLayout *documentLayout = qobject_cast<TextEditDocumentLayout*>(doc->documentLayout()); TextEditDocumentLayout *documentLayout = qobject_cast<TextEditDocumentLayout*>(doc->documentLayout());
Q_ASSERT(documentLayout); Q_ASSERT(documentLayout);
QTextBlock block = textCursor().block(); QTextBlock block = textCursor().block();
qDebug() << "collapse at block" << block.blockNumber();
while (block.isValid()) { while (block.isValid()) {
if (TextBlockUserData::canCollapse(block)) { qDebug() << "test block" << block.blockNumber();
if ((block.next().userState()) >> 8 == (textCursor().block().userState() >> 8)) if (TextBlockUserData::canCollapse(block) && block.next().isVisible()) {
if ((block.next().userState()) >> 8 <= (textCursor().block().userState() >> 8))
break; break;
} }
block = block.previous(); block = block.previous();
} }
qDebug() << "found" << block.blockNumber();
if (block.isValid()) { if (block.isValid()) {
TextBlockUserData::doCollapse(block, false); TextBlockUserData::doCollapse(block, false);
d->moveCursorVisible(); d->moveCursorVisible();
@@ -3238,6 +3391,14 @@ void BaseTextEditor::cut()
QPlainTextEdit::cut(); QPlainTextEdit::cut();
} }
void BaseTextEditor::paste()
{
if (d->m_inBlockSelectionMode) {
d->removeBlockSelection();
}
QPlainTextEdit::paste();
}
QMimeData *BaseTextEditor::createMimeDataFromSelection() const QMimeData *BaseTextEditor::createMimeDataFromSelection() const
{ {
if (d->m_inBlockSelectionMode) { if (d->m_inBlockSelectionMode) {

View File

@@ -169,6 +169,8 @@ public:
static MatchType checkClosedParenthesis(QTextCursor *cursor, QChar c); static MatchType checkClosedParenthesis(QTextCursor *cursor, QChar c);
static MatchType matchCursorBackward(QTextCursor *cursor); static MatchType matchCursorBackward(QTextCursor *cursor);
static MatchType matchCursorForward(QTextCursor *cursor); static MatchType matchCursorForward(QTextCursor *cursor);
static bool findPreviousOpenParenthesis(QTextCursor *cursor, bool select = false);
static bool findNextClosingParenthesis(QTextCursor *cursor, bool select = false);
private: private:
@@ -298,6 +300,8 @@ public:
void setReadOnly(bool b); void setReadOnly(bool b);
void setTextCursor(const QTextCursor &cursor);
public slots: public slots:
void setDisplayName(const QString &title); void setDisplayName(const QString &title);
virtual void setFontSettings(const TextEditor::FontSettings &); virtual void setFontSettings(const TextEditor::FontSettings &);
@@ -305,6 +309,7 @@ public slots:
virtual void unCommentSelection(); virtual void unCommentSelection();
virtual void setStorageSettings(const TextEditor::StorageSettings &); virtual void setStorageSettings(const TextEditor::StorageSettings &);
void paste();
void cut(); void cut();
void zoomIn(int range = 1); void zoomIn(int range = 1);
@@ -316,6 +321,14 @@ public slots:
void expand(); void expand();
void selectEncoding(); void selectEncoding();
void gotoBlockStart();
void gotoBlockEnd();
void gotoBlockStartWithSelection();
void gotoBlockEndWithSelection();
void selectBlockUp();
void selectBlockDown();
signals: signals:
void changed(); void changed();
@@ -356,7 +369,6 @@ private:
Internal::BaseTextEditorPrivate *d; Internal::BaseTextEditorPrivate *d;
friend class Internal::BaseTextEditorPrivate; friend class Internal::BaseTextEditorPrivate;
public: public:
QWidget *extraArea() const; QWidget *extraArea() const;
virtual int extraAreaWidth(int *markWidthPtr = 0) const; virtual int extraAreaWidth(int *markWidthPtr = 0) const;
@@ -372,8 +384,16 @@ public:
void ensureCursorVisible(); void ensureCursorVisible();
void setExtraExtraSelections(const QList<QTextEdit::ExtraSelection> &selections); enum ExtraSelectionKind {
QList<QTextEdit::ExtraSelection> extraExtraSelections() const; CurrentLineSelection,
ParenthesesMatchingSelection,
CodeWarningsSelection,
CodeSemanticsSelection,
OtherSelection,
NExtraSelectionKinds
};
void setExtraSelections(ExtraSelectionKind kind, const QList<QTextEdit::ExtraSelection> &selections);
QList<QTextEdit::ExtraSelection> extraSelections(ExtraSelectionKind kind) const;
struct BlockRange { struct BlockRange {
BlockRange():first(0), last(-1){} BlockRange():first(0), last(-1){}
@@ -418,7 +438,6 @@ protected slots:
signals: signals:
void markRequested(TextEditor::ITextEditor *editor, int line);
void requestBlockUpdate(const QTextBlock &); void requestBlockUpdate(const QTextBlock &);
void requestAutoCompletion(ITextEditable *editor, bool forced); void requestAutoCompletion(ITextEditable *editor, bool forced);

View File

@@ -204,8 +204,7 @@ public:
QObject *m_actionHack; QObject *m_actionHack;
QList<QTextEdit::ExtraSelection> m_extraSelections; QList<QTextEdit::ExtraSelection> m_extraSelections[BaseTextEditor::NExtraSelectionKinds];
QList<QTextEdit::ExtraSelection> m_extraExtraSelections;
// block selection mode // block selection mode
bool m_inBlockSelectionMode; bool m_inBlockSelectionMode;
@@ -216,6 +215,7 @@ public:
void removeBlockSelection(const QString &text = QString()); void removeBlockSelection(const QString &text = QString());
QTextCursor m_findScope; QTextCursor m_findScope;
QTextCursor m_selectBlockAnchor;
void moveCursorVisible(); void moveCursorVisible();
}; };

View File

@@ -44,6 +44,7 @@
#include <QtGui/QIcon> #include <QtGui/QIcon>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QMenu;
class QTextBlock; class QTextBlock;
QT_END_NAMESPACE QT_END_NAMESPACE
@@ -124,6 +125,7 @@ public:
signals: signals:
void contentsChanged(); void contentsChanged();
void markRequested(TextEditor::ITextEditor *editor, int line); void markRequested(TextEditor::ITextEditor *editor, int line);
void markContextMenuRequested(TextEditor::ITextEditor *editor, int line, QMenu *menu);
void tooltipRequested(TextEditor::ITextEditor *editor, const QPoint &globalPos, int position); void tooltipRequested(TextEditor::ITextEditor *editor, const QPoint &globalPos, int position);
void contextHelpIdRequested(TextEditor::ITextEditor *editor, int position); void contextHelpIdRequested(TextEditor::ITextEditor *editor, int position);
}; };

View File

@@ -67,6 +67,9 @@ TextEditorActionHandler::TextEditorActionHandler(Core::ICore *core,
= m_collapseAction = m_expandAction = m_collapseAction = m_expandAction
= m_deleteLineAction = m_selectEncodingAction = m_deleteLineAction = m_selectEncodingAction
= m_increaseFontSizeAction = m_decreaseFontSizeAction = m_increaseFontSizeAction = m_decreaseFontSizeAction
= m_gotoBlockStartAction = m_gotoBlockStartWithSelectionAction
= m_gotoBlockEndAction = m_gotoBlockEndWithSelectionAction
= m_selectBlockUpAction = m_selectBlockDownAction
= 0; = 0;
m_contextId << m_core->uniqueIDManager()->uniqueIdentifier(context); m_contextId << m_core->uniqueIDManager()->uniqueIdentifier(context);
@@ -161,13 +164,11 @@ void TextEditorActionHandler::createActions()
command = am->registerAction(m_collapseAction, Constants::COLLAPSE, m_contextId); command = am->registerAction(m_collapseAction, Constants::COLLAPSE, m_contextId);
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+<"))); command->setDefaultKeySequence(QKeySequence(tr("Ctrl+<")));
connect(m_collapseAction, SIGNAL(triggered()), this, SLOT(collapse())); connect(m_collapseAction, SIGNAL(triggered()), this, SLOT(collapse()));
advancedMenu->addAction(command);
m_expandAction = new QAction(tr("Expand"), this); m_expandAction = new QAction(tr("Expand"), this);
command = am->registerAction(m_expandAction, Constants::EXPAND, m_contextId); command = am->registerAction(m_expandAction, Constants::EXPAND, m_contextId);
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+>"))); command->setDefaultKeySequence(QKeySequence(tr("Ctrl+>")));
connect(m_expandAction, SIGNAL(triggered()), this, SLOT(expand())); connect(m_expandAction, SIGNAL(triggered()), this, SLOT(expand()));
advancedMenu->addAction(command);
m_unCollapseAllAction = new QAction(tr("(Un)&Collapse All"), this); m_unCollapseAllAction = new QAction(tr("(Un)&Collapse All"), this);
command = am->registerAction(m_unCollapseAllAction, Constants::UN_COLLAPSE_ALL, m_contextId); command = am->registerAction(m_unCollapseAllAction, Constants::UN_COLLAPSE_ALL, m_contextId);
@@ -185,6 +186,36 @@ void TextEditorActionHandler::createActions()
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+-"))); command->setDefaultKeySequence(QKeySequence(tr("Ctrl+-")));
connect(m_decreaseFontSizeAction, SIGNAL(triggered()), this, SLOT(decreaseFontSize())); connect(m_decreaseFontSizeAction, SIGNAL(triggered()), this, SLOT(decreaseFontSize()));
advancedMenu->addAction(command); advancedMenu->addAction(command);
m_gotoBlockStartAction = new QAction(tr("Goto Block Start"), this);
command = am->registerAction(m_gotoBlockStartAction, Constants::GOTO_BLOCK_START, m_contextId);
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+[")));
connect(m_gotoBlockStartAction, SIGNAL(triggered()), this, SLOT(gotoBlockStart()));
m_gotoBlockEndAction = new QAction(tr("Goto Block End"), this);
command = am->registerAction(m_gotoBlockEndAction, Constants::GOTO_BLOCK_END, m_contextId);
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+]")));
connect(m_gotoBlockEndAction, SIGNAL(triggered()), this, SLOT(gotoBlockEnd()));
m_gotoBlockStartWithSelectionAction = new QAction(tr("Goto Block Start With Selection"), this);
command = am->registerAction(m_gotoBlockStartWithSelectionAction, Constants::GOTO_BLOCK_START_WITH_SELECTION, m_contextId);
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+{")));
connect(m_gotoBlockStartWithSelectionAction, SIGNAL(triggered()), this, SLOT(gotoBlockStartWithSelection()));
m_gotoBlockEndWithSelectionAction = new QAction(tr("Goto Block End With Selection"), this);
command = am->registerAction(m_gotoBlockEndWithSelectionAction, Constants::GOTO_BLOCK_END_WITH_SELECTION, m_contextId);
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+}")));
connect(m_gotoBlockEndWithSelectionAction, SIGNAL(triggered()), this, SLOT(gotoBlockEndWithSelection()));
m_selectBlockUpAction= new QAction(tr("Select Block Up"), this);
command = am->registerAction(m_selectBlockUpAction, Constants::SELECT_BLOCK_UP, m_contextId);
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+U")));
connect(m_selectBlockUpAction, SIGNAL(triggered()), this, SLOT(selectBlockUp()));
m_selectBlockDownAction= new QAction(tr("Select Block Down"), this);
command = am->registerAction(m_selectBlockDownAction, Constants::SELECT_BLOCK_DOWN, m_contextId);
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+U")));
connect(m_selectBlockDownAction, SIGNAL(triggered()), this, SLOT(selectBlockDown()));
} }
bool TextEditorActionHandler::supportsAction(const QString & /*id */) const bool TextEditorActionHandler::supportsAction(const QString & /*id */) const
@@ -229,35 +260,30 @@ void TextEditorActionHandler::updateActions()
void TextEditorActionHandler::updateActions(UpdateMode um) void TextEditorActionHandler::updateActions(UpdateMode um)
{ {
if (m_pasteAction) if (!m_initialized)
m_pasteAction->setEnabled(um != NoEditor); return;
if (m_selectAllAction) m_pasteAction->setEnabled(um != NoEditor);
m_selectAllAction->setEnabled(um != NoEditor); m_selectAllAction->setEnabled(um != NoEditor);
if (m_gotoAction) m_gotoAction->setEnabled(um != NoEditor);
m_gotoAction->setEnabled(um != NoEditor); m_selectEncodingAction->setEnabled(um != NoEditor);
if (m_selectEncodingAction) m_printAction->setEnabled(um != NoEditor);
m_selectEncodingAction->setEnabled(um != NoEditor); m_formatAction->setEnabled((m_optionalActions & Format) && um != NoEditor);
if (m_printAction) m_unCommentSelectionAction->setEnabled((m_optionalActions & UnCommentSelection) && um != NoEditor);
m_printAction->setEnabled(um != NoEditor); m_collapseAction->setEnabled(um != NoEditor);
if (m_formatAction) m_expandAction->setEnabled(um != NoEditor);
m_formatAction->setEnabled((m_optionalActions & Format) && um != NoEditor); m_unCollapseAllAction->setEnabled((m_optionalActions & UnCollapseAll) && um != NoEditor);
if (m_unCommentSelectionAction) m_decreaseFontSizeAction->setEnabled(um != NoEditor);
m_unCommentSelectionAction->setEnabled((m_optionalActions & UnCommentSelection) && um != NoEditor); m_increaseFontSizeAction->setEnabled(um != NoEditor);
if (m_collapseAction) m_gotoBlockStartAction->setEnabled(um != NoEditor);
m_collapseAction->setEnabled(um != NoEditor); m_gotoBlockStartWithSelectionAction->setEnabled(um != NoEditor);
if (m_expandAction) m_gotoBlockEndAction->setEnabled(um != NoEditor);
m_expandAction->setEnabled(um != NoEditor); m_gotoBlockEndWithSelectionAction->setEnabled(um != NoEditor);
if (m_unCollapseAllAction) m_selectBlockUpAction->setEnabled(um != NoEditor);
m_unCollapseAllAction->setEnabled((m_optionalActions & UnCollapseAll) && um != NoEditor); m_selectBlockDownAction->setEnabled(um != NoEditor);
if (m_decreaseFontSizeAction)
m_decreaseFontSizeAction->setEnabled(um != NoEditor); m_visualizeWhitespaceAction->setEnabled(um != NoEditor);
if (m_increaseFontSizeAction) if (m_currentEditor)
m_increaseFontSizeAction->setEnabled(um != NoEditor); m_visualizeWhitespaceAction->setChecked(m_currentEditor->displaySettings().m_visualizeWhitespace);
if (m_visualizeWhitespaceAction) {
m_visualizeWhitespaceAction->setEnabled(um != NoEditor);
if (m_currentEditor)
m_visualizeWhitespaceAction->setChecked(m_currentEditor->displaySettings().m_visualizeWhitespace);
}
if (m_textWrappingAction) { if (m_textWrappingAction) {
m_textWrappingAction->setEnabled(um != NoEditor); m_textWrappingAction->setEnabled(um != NoEditor);
if (m_currentEditor) if (m_currentEditor)
@@ -365,54 +391,31 @@ void TextEditorActionHandler::setTextWrapping(bool checked)
} }
} }
void TextEditorActionHandler::unCommentSelection() #define FUNCTION(funcname) void TextEditorActionHandler::funcname ()\
{ {\
if (m_currentEditor) if (m_currentEditor)\
m_currentEditor->unCommentSelection(); m_currentEditor->funcname ();\
} }
#define FUNCTION2(funcname, funcname2) void TextEditorActionHandler::funcname ()\
void TextEditorActionHandler::deleteLine() {\
{ if (m_currentEditor)\
if (m_currentEditor) m_currentEditor->funcname2 ();\
m_currentEditor->deleteLine();
}
void TextEditorActionHandler::unCollapseAll()
{
if (m_currentEditor)
m_currentEditor->unCollapseAll();
}
void TextEditorActionHandler::collapse()
{
if (m_currentEditor)
m_currentEditor->collapse();
}
void TextEditorActionHandler::expand()
{
if (m_currentEditor)
m_currentEditor->expand();
}
void TextEditorActionHandler::selectEncoding()
{
if (m_currentEditor)
m_currentEditor->selectEncoding();
}
void TextEditorActionHandler::increaseFontSize()
{
if (m_currentEditor)
m_currentEditor->zoomIn();
}
void TextEditorActionHandler::decreaseFontSize()
{
if (m_currentEditor)
m_currentEditor->zoomOut();
} }
FUNCTION(unCommentSelection)
FUNCTION(deleteLine)
FUNCTION(unCollapseAll)
FUNCTION(collapse)
FUNCTION(expand)
FUNCTION2(increaseFontSize, zoomIn)
FUNCTION2(decreaseFontSize, zoomOut)
FUNCTION(selectEncoding)
FUNCTION(gotoBlockStart)
FUNCTION(gotoBlockEnd)
FUNCTION(gotoBlockStartWithSelection)
FUNCTION(gotoBlockEndWithSelection)
FUNCTION(selectBlockUp)
FUNCTION(selectBlockDown)
void TextEditorActionHandler::updateCurrentEditor(Core::IContext *object) void TextEditorActionHandler::updateCurrentEditor(Core::IContext *object)
{ {

View File

@@ -109,6 +109,12 @@ private slots:
void selectEncoding(); void selectEncoding();
void increaseFontSize(); void increaseFontSize();
void decreaseFontSize(); void decreaseFontSize();
void gotoBlockStart();
void gotoBlockEnd();
void gotoBlockStartWithSelection();
void gotoBlockEndWithSelection();
void selectBlockUp();
void selectBlockDown();
void updateCurrentEditor(Core::IContext *object); void updateCurrentEditor(Core::IContext *object);
private: private:
@@ -131,6 +137,12 @@ private:
QAction *m_selectEncodingAction; QAction *m_selectEncodingAction;
QAction *m_increaseFontSizeAction; QAction *m_increaseFontSizeAction;
QAction *m_decreaseFontSizeAction; QAction *m_decreaseFontSizeAction;
QAction *m_gotoBlockStartAction;
QAction *m_gotoBlockEndAction;
QAction *m_gotoBlockStartWithSelectionAction;
QAction *m_gotoBlockEndWithSelectionAction;
QAction *m_selectBlockUpAction;
QAction *m_selectBlockDownAction;
uint m_optionalActions; uint m_optionalActions;
QPointer<BaseTextEditor> m_currentEditor; QPointer<BaseTextEditor> m_currentEditor;

View File

@@ -48,9 +48,17 @@ const char * const UN_COLLAPSE_ALL = "TextEditor.UnCollapseAll";
const char * const AUTO_INDENT_SELECTION = "TextEditor.AutoIndentSelection"; const char * const AUTO_INDENT_SELECTION = "TextEditor.AutoIndentSelection";
const char * const INCREASE_FONT_SIZE = "TextEditor.IncreaseFontSize"; const char * const INCREASE_FONT_SIZE = "TextEditor.IncreaseFontSize";
const char * const DECREASE_FONT_SIZE = "TextEditor.DecreaseFontSize"; const char * const DECREASE_FONT_SIZE = "TextEditor.DecreaseFontSize";
const char * const GOTO_BLOCK_START = "TextEditor.GotoBlockStart";
const char * const GOTO_BLOCK_START_WITH_SELECTION = "TextEditor.GotoBlockStartWithSelection";
const char * const GOTO_BLOCK_END = "TextEditor.GotoBlockEnd";
const char * const GOTO_BLOCK_END_WITH_SELECTION = "TextEditor.GotoBlockEndWithSelection";
const char * const SELECT_BLOCK_UP = "TextEditor.SelectBlockUp";
const char * const SELECT_BLOCK_DOWN = "TextEditor.SelectBlockDown";
const char * const DELETE_LINE = "TextEditor.DeleteLine"; const char * const DELETE_LINE = "TextEditor.DeleteLine";
const char * const DELETE_WORD = "TextEditor.DeleteWord"; const char * const DELETE_WORD = "TextEditor.DeleteWord";
const char * const SELECT_ENCODING = "TextEditor.SelectEncoding"; const char * const SELECT_ENCODING = "TextEditor.SelectEncoding";
const char * const GOTO_OPENING_PARENTHESIS = "TextEditor.GotoOpeningParenthesis";
const char * const GOTO_CLOSING_PARENTHESIS = "TextEditor.GotoOpeningParenthesis";
const char * const C_TEXTEDITOR_MIMETYPE_TEXT = "text/plain"; const char * const C_TEXTEDITOR_MIMETYPE_TEXT = "text/plain";
const char * const C_TEXTEDITOR_MIMETYPE_XML = "application/xml"; const char * const C_TEXTEDITOR_MIMETYPE_XML = "application/xml";

View File

@@ -225,23 +225,12 @@ void VCSBaseEditor::mouseMoveEvent(QMouseEvent *e)
sel.format.setFontUnderline(true); sel.format.setFontUnderline(true);
change = changeUnderCursor(cursor); change = changeUnderCursor(cursor);
sel.format.setProperty(QTextFormat::UserProperty, change); sel.format.setProperty(QTextFormat::UserProperty, change);
bool found = false; setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>() << sel);
foreach (QTextEdit::ExtraSelection es, extraSelections()) { viewport()->setCursor(Qt::PointingHandCursor);
if (es.format.stringProperty(QTextFormat::UserProperty) == sel.format.stringProperty(QTextFormat::UserProperty)) {
found = true;
break;
}
}
if (!found) {
setExtraSelections(QList<QTextEdit::ExtraSelection>() << sel);
viewport()->setCursor(Qt::PointingHandCursor);
}
} else {
if (!extraSelections().isEmpty()) {
setExtraSelections(QList<QTextEdit::ExtraSelection>());
viewport()->setCursor(Qt::IBeamCursor);
}
} }
} else {
setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>());
viewport()->setCursor(Qt::IBeamCursor);
} }
TextEditor::BaseTextEditor::mouseMoveEvent(e); TextEditor::BaseTextEditor::mouseMoveEvent(e);
} }