Merge remote-tracking branch 'origin/2.5'

Conflicts:
	qtcreator.pri

Change-Id: Ic24b756b41d2a13f3d696dee69553d2c3241ab95
This commit is contained in:
Eike Ziller
2012-03-14 09:33:25 +01:00
33 changed files with 278 additions and 132 deletions

48
dist/changes-2.5.0 vendored
View File

@@ -10,6 +10,8 @@ git log --cherry-pick --pretty=oneline v2.4.0...origin/2.5
General General
* Add a keyboard shortcut (Alt) to the locator to display the full path to * Add a keyboard shortcut (Alt) to the locator to display the full path to
a located file (QTCREATORBUG-3805) a located file (QTCREATORBUG-3805)
* Add "Search Again" to recent searches (QTCREATORBUG-621)
* Allow multiple parallel searches (QTCREATORBUG-6101)
Editing Editing
* Use the QML/JS editor for opening json files (QTCREATORBUG-4639) * Use the QML/JS editor for opening json files (QTCREATORBUG-4639)
@@ -28,10 +30,36 @@ Editing
* Fix layout update when folding/unfolding regions (QTCREATORBUG-6666) * Fix layout update when folding/unfolding regions (QTCREATORBUG-6666)
* Fix position of code-assist popup when cursor is outside viewport * Fix position of code-assist popup when cursor is outside viewport
(QTCREATORBUG-6843) (QTCREATORBUG-6843)
* Add experimental plugin for showing "TODO"s in files
[by Dmitry Savchenko]
* Add "Open with" context menu in resource editor (QTCREATORBUG-4224)
* Add task indicators in the left margin of a line
Managing Projects Managing Projects
* Add facility to change multiple environment variables in the
build and run settings at the same time
Debugging Debugging
* Improve display of vtables and dynamic types (QTCREATORBUG-6933 et al)
* Adjust QDir and QFileInfo gdb pretty printer after Qt 4.8 changes
and various others for Qt 5.0
* Adjust std::map dumper for gcc 4.6
* Adjust to new *stopped output notifications of gdb 7.4
* Add pretty printers for std::shared_ptr, std::unique_ptr, std::array,
std::complex, boost::posix_time::{ptime,time_duration},
boost::gregorian::date
* Improve remote debugging facilities including new convenience
dialogs like "Attach to Running Remote Process"
* Improve per-type and per-variable selection of display formats
* Add display variants for map-like types (std::map, QMap, QHash etc)
* Make "gdb startup script" directly editable
* Improve expansion behaviour of pinned tooltips (QTCREATORBUG-6554)
* Prevent automatic loading of incompatible dumpers
* Make Shift-F5 exit when debugging a core file (QTCREATORBUG-6111)
* Make popping up the output pane optional (QTCREATORBUG-6764)
* Make entering commands in the log view more convenient
* Re-enable debugging of Python scripts
* Add pretty-printing for D arrays and strings
Debugging QML/JS Debugging QML/JS
* Relocate breakpoints to next executable code * Relocate breakpoints to next executable code
@@ -39,6 +67,8 @@ Debugging QML/JS
* Spruce up the script console for evaluating QML/JS expressions * Spruce up the script console for evaluating QML/JS expressions
Analyzing Code Analyzing Code
* Fix message for "incompatible" builds (QTCREATORBUG-7011)
* Fix suppression dialog (QTCREATORBUG-6500)
C++ Support C++ Support
* Fix completion and the dot-to-arrow conversion not triggering reliably * Fix completion and the dot-to-arrow conversion not triggering reliably
@@ -76,6 +106,11 @@ C++ Support
* Add "rearrange parameter list" refactoring action [by Bojan Petrovic] * Add "rearrange parameter list" refactoring action [by Bojan Petrovic]
* Add indent/unindent actions shortcut [by Adam Treat] * Add indent/unindent actions shortcut [by Adam Treat]
* Improve sorting of completion items (QTCREATORBUG-6404) * Improve sorting of completion items (QTCREATORBUG-6404)
* Improve C++11 lambda support, including formatting
* Fix "go to definition" of macros (QTCREATORBUG-2240, QTCREATORBUG-6175,
QTCREATORBUG-6848, QTCREATORBUG-7008, QTCREATORBUG-7009)
* Fix completion by not adding parentheses when completing dereferenced
function
QML/JS Support QML/JS Support
* Add correct scoping for signal handlers; enables completion of signal * Add correct scoping for signal handlers; enables completion of signal
@@ -102,7 +137,9 @@ Help
Platform Specific Platform Specific
Mac Mac
* Pass architecture and bit width from the tool chain build setting to Qmake (QTCREATORBUG-6088) * Fix adding Qt version on Mac OS X Lion (QTCREATORBUG-6222)
* Pass architecture and bit width from the tool chain build setting
to qmake (QTCREATORBUG-6088)
Linux (GNOME and KDE) Linux (GNOME and KDE)
@@ -115,8 +152,17 @@ Remote Linux Support
Qt Designer Qt Designer
FakeVim FakeVim
* Implement Ctrl-a, Ctrl-x, &, gm, `., '., :<x>%, ciw.
* Add handling of number key block
* Fix cursor column after up/down in replace mode
* Fix case sensitivity of parsing of codes like "<Esc>" in mappings
* Overhaul register handling
* Add old-style settings of for 'bs' (QTCREATORBUG-6640)
* Fix off-by-one error when creating a single line range (QTCREATORBUG-6630)
Version control plugins Version control plugins
* Rename the ScmGit plugin to Git
* Rename the VCSBase plugin to VcsBase
Additional credits go to: Additional credits go to:

View File

@@ -105,21 +105,24 @@ HTML.footer = \
" </div> \n" \ " </div> \n" \
" <div class=\"footer\">\n" \ " <div class=\"footer\">\n" \
" <p>\n" \ " <p>\n" \
" <acronym title=\"Copyright\">&copy;</acronym> 2008-2012 Nokia Corporation and/or its\n" \
" subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation \n" \
" in Finland and/or other countries worldwide.</p>\n" \
" <p>\n" \ " <p>\n" \
" All other trademarks are property of their respective owners. <a title=\"Privacy Policy\"\n" \ " <acronym title=\"Copyright\">&copy;</acronym> 2012 Nokia Corporation and/or its\n" \
" href=\"http://qt.nokia.com/about/privacy-policy\">Privacy Policy</a></p>\n" \ " subsidiaries. Documentation contributions included herein are the copyrights of\n" \
" their respective owners.</p>\n" \
" <br />\n" \ " <br />\n" \
" <p>\n" \ " <p>\n" \
" Licensees holding valid Qt Commercial licenses may use this document in accordance with the" \ " The documentation provided herein is licensed under the terms of the\n" \
" Qt Commercial License Agreement provided with the Software or, alternatively, in accordance" \ " <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU Free Documentation\n" \
" with the terms contained in a written agreement between you and Nokia.</p>\n" \ " License version 1.3</a> as published by the Free Software Foundation.</p>\n" \
" <p>\n" \ " <p>\n" \
" Alternatively, this document may be used under the terms of the <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU\n" \ " Documentation sources may be obtained from <a href=\"http://www.qt-project.org\">\n" \
" Free Documentation License version 1.3</a>\n" \ " www.qt-project.org</a>.</p>\n" \
" as published by the Free Software Foundation.</p>\n" \ " <br />\n" \
" <p>\n" \
" Nokia, Qt and their respective logos are trademarks of Nokia Corporation \n" \
" in Finland and/or other countries worldwide. All other trademarks are property\n" \
" of their respective owners. <a title=\"Privacy Policy\"\n" \
" href=\"http://en.gitorious.org/privacy_policy/\">Privacy Policy</a></p>\n" \
" </div>\n" \ " </div>\n" \
"\n" \ "\n" \
" <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n" \ " <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n" \

View File

@@ -23,22 +23,24 @@ HTML.footer = \
" </div>\n" \ " </div>\n" \
"</div> \n" \ "</div> \n" \
"<div class=\"footer\">\n" \ "<div class=\"footer\">\n" \
" <p>\n" \ " <p>\n" \
" <acronym title=\"Copyright\">&copy;</acronym> 2008-2012 Nokia Corporation and/or its\n" \ " <acronym title=\"Copyright\">&copy;</acronym> 2012 Nokia Corporation and/or its\n" \
" subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation \n" \ " subsidiaries. Documentation contributions included herein are the copyrights of\n" \
" in Finland and/or other countries worldwide.</p>\n" \ " their respective owners.</p>\n" \
" <p>\n" \ " <br />\n" \
" All other trademarks are property of their respective owners. <a title=\"Privacy Policy\"\n" \ " <p>\n" \
" href=\"http://qt.nokia.com/about/privacy-policy\">Privacy Policy</a></p>\n" \ " The documentation provided herein is licensed under the terms of the\n" \
" <br />\n" \ " <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU Free Documentation\n" \
" <p>\n" \ " License version 1.3</a> as published by the Free Software Foundation.</p>\n" \
" Licensees holding valid Qt Commercial licenses may use this document in accordance with the" \ " <p>\n" \
" Qt Commercial License Agreement provided with the Software or, alternatively, in accordance" \ " Documentation sources may be obtained from <a href=\"http://www.qt-project.org\">\n" \
" with the terms contained in a written agreement between you and Nokia.</p>\n" \ " www.qt-project.org</a>.</p>\n" \
" <p>\n" \ " <br />\n" \
" Alternatively, this document may be used under the terms of the <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU\n" \ " <p>\n" \
" Free Documentation License version 1.3</a>\n" \ " Nokia, Qt and their respective logos are trademarks of Nokia Corporation \n" \
" as published by the Free Software Foundation.</p>\n" \ " in Finland and/or other countries worldwide. All other trademarks are property\n" \
" of their respective owners. <a title=\"Privacy Policy\"\n" \
" href=\"http://en.gitorious.org/privacy_policy/\">Privacy Policy</a></p>\n" \
"</div>\n" \ "</div>\n" \
# Files not referenced in any qdoc file. # Files not referenced in any qdoc file.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -10,16 +10,15 @@
\o Select \gui {Tools > Options > Linux Devices > Device \o Select \gui {Tools > Options > Linux Devices > Device
Configurations > Generate SSH Key}. Configurations > Generate SSH Key}.
\o Click \gui {Generate SSH Key}.
\image qtcreator-ssh-key-configuration.png "SSH Key Configuration dialog" \image qtcreator-ssh-key-configuration.png "SSH Key Configuration dialog"
\o Click \gui {Save Public Key} to select the location to save the \o In the \gui {Private key file} field, select the location to save
public key. the private key.
\o Click \gui {Save Private Key} to specify the location to save the The \gui {Public key file} field displays the location to save the
private key. corresponding public key.
\o Click \gui Close to close the dialog. \o Select \gui {Generate And Save Key Pair} to generate and save the
keys at the specified locations.
\endlist \endlist

View File

@@ -37,10 +37,10 @@ import shutil
from glob import glob from glob import glob
ignoreErrors = False ignoreErrors = False
is_debug_build = False debug_build = False
def usage(): def usage():
print "Usage: %s <creator_install_dir> [qmake_path]" % os.path.basename(sys.argv[0]) print "Usage: %s <creator_install_dir> [qmake_path]" % os.path.basename(sys.argv[0])
def which(program): def which(program):
def is_exe(fpath): def is_exe(fpath):
@@ -64,15 +64,15 @@ def which(program):
return None return None
def check_debug(fpath): def is_debug(fpath):
# bootstrap exception # bootstrap exception
if fpath.endswith('QtCore4d.dll'): if fpath.endswith('QtCore4d.dll'):
return True return True
output = subprocess.check_output(['dumpbin', '/imports', fpath]) output = subprocess.check_output(['dumpbin', '/imports', fpath])
return output.find('QtCored4.dll') != -1 return output.find('QtCored4.dll') != -1
def check_debug_build(install_dir): def is_debug_build(install_dir):
return check_debug(os.path.join(install_dir, 'bin', 'qtcreator.exe')) return is_debug(os.path.join(install_dir, 'bin', 'qtcreator.exe'))
def op_failed(details = None): def op_failed(details = None):
if details != None: if details != None:
@@ -117,24 +117,23 @@ def fix_rpaths(chrpath_bin, install_dir):
filenames = [filename for filename in filenames if check_unix_library_helper(dirpath, filename)] filenames = [filename for filename in filenames if check_unix_library_helper(dirpath, filename)]
fix_rpaths_helper(chrpath_bin, install_dir, dirpath, filenames) fix_rpaths_helper(chrpath_bin, install_dir, dirpath, filenames)
def ignore_pattern_helper(filename): def windows_debug_files_filter(filename):
ignore_patterns = ['.lib', '.pdb', '.exp', '.ilk', '.dll'] ignore_patterns = ['.lib', '.pdb', '.exp', '.ilk']
for ip in ignore_patterns: for ip in ignore_patterns:
if filename.endswith(ip): if filename.endswith(ip):
return False return True
return True return False
def copy_ignore_patterns_helper(dir, filenames): def copy_ignore_patterns_helper(dir, filenames):
if not sys.platform.startswith('win'): if not sys.platform.startswith('win'):
return filenames return filenames
useful = filter(ignore_pattern_helper, filenames) if debug_build:
if is_debug_build: wrong_dlls = filter(lambda filename: filename.endswith('.dll') and not is_debug(os.path.join(dir, filename)), filenames)
dlls = filter(lambda filename: filename.endswith('.dll') and check_debug(os.path.join(dir, filename)), filenames)
else: else:
dlls = filter(lambda filename: filename.endswith('.dll') and not check_debug(os.path.join(dir, filename)), filenames) wrong_dlls = filter(lambda filename: filename.endswith('.dll') and is_debug(os.path.join(dir, filename)), filenames)
filenames = useful + dlls filenames = wrong_dlls + filter(windows_debug_files_filter, filenames)
return filenames return filenames
def copy_qt_libs(install_dir, qt_libs_dir, qt_plugin_dir, qt_import_dir, plugins, imports): def copy_qt_libs(install_dir, qt_libs_dir, qt_plugin_dir, qt_import_dir, plugins, imports):
@@ -151,10 +150,10 @@ def copy_qt_libs(install_dir, qt_libs_dir, qt_plugin_dir, qt_import_dir, plugins
dest = os.path.join(install_dir, 'lib', 'qtcreator') dest = os.path.join(install_dir, 'lib', 'qtcreator')
if sys.platform.startswith('win'): if sys.platform.startswith('win'):
if is_debug_build: if debug_build:
libraries = filter(lambda library: check_debug(library), libraries) libraries = filter(lambda library: is_debug(library), libraries)
else: else:
libraries = filter(lambda library: not check_debug(library), libraries) libraries = filter(lambda library: not is_debug(library), libraries)
for library in libraries: for library in libraries:
print library, '->', dest print library, '->', dest
@@ -186,7 +185,7 @@ def copy_qt_libs(install_dir, qt_libs_dir, qt_plugin_dir, qt_import_dir, plugins
shutil.copytree(os.path.join(qt_import_dir, qtimport), target, ignore=copy_ignore_func, symlinks=True) shutil.copytree(os.path.join(qt_import_dir, qtimport), target, ignore=copy_ignore_func, symlinks=True)
def copy_translations(install_dir, qt_tr_dir, tr_catalogs): def copy_translations(install_dir, qt_tr_dir, tr_catalogs):
langs=[] langs = []
tr_dir = os.path.join(install_dir, 'share', 'qtcreator', 'translations') tr_dir = os.path.join(install_dir, 'share', 'qtcreator', 'translations')
p = re.compile(r'_(.*).qm') p = re.compile(r'_(.*).qm')
for dirpath, dirnames, filenames in os.walk(tr_dir): for dirpath, dirnames, filenames in os.walk(tr_dir):
@@ -210,11 +209,9 @@ def readQmakeVar(qmake_bin, var):
return pipe.read().rstrip('\n') return pipe.read().rstrip('\n')
def main(): def main():
generateMode = False
try: try:
opts, args = getopt.gnu_getopt(sys.argv[1:], 'hi', ['help', 'ignore-errors']) opts, args = getopt.gnu_getopt(sys.argv[1:], 'hi', ['help', 'ignore-errors'])
except: except:
print str(err)
usage() usage()
sys.exit(2) sys.exit(2)
for o, a in opts: for o, a in opts:
@@ -227,10 +224,10 @@ def main():
print "Note: Ignoring all errors" print "Note: Ignoring all errors"
if len(args) < 1: if len(args) < 1:
usage() usage()
sys.exit(2) sys.exit(2)
install_dir=args[0] install_dir = args[0]
qmake_bin = 'qmake' qmake_bin = 'qmake'
if len(args) > 1: if len(args) > 1:
@@ -238,8 +235,8 @@ def main():
qmake_bin = which(qmake_bin) qmake_bin = which(qmake_bin)
if qmake_bin == None: if qmake_bin == None:
print "Cannot find required binary 'qmake'." print "Cannot find required binary 'qmake'."
sys.exit(2) sys.exit(2)
if not sys.platform.startswith('win'): if not sys.platform.startswith('win'):
chrpath_bin = which('chrpath') chrpath_bin = which('chrpath')
@@ -257,14 +254,14 @@ def main():
tr_catalogs = ['assistant', 'designer', 'qt', 'qt_help'] tr_catalogs = ['assistant', 'designer', 'qt', 'qt_help']
if sys.platform.startswith('win'): if sys.platform.startswith('win'):
global is_debug_build global debug_build
is_debug_build = check_debug_build(install_dir) debug_build = is_debug_build(install_dir)
copy_qt_libs(install_dir, QT_INSTALL_LIBS, QT_INSTALL_PLUGINS, QT_INSTALL_IMPORTS, plugins, imports) copy_qt_libs(install_dir, QT_INSTALL_LIBS, QT_INSTALL_PLUGINS, QT_INSTALL_IMPORTS, plugins, imports)
copy_translations(install_dir, QT_INSTALL_TRANSLATIONS, tr_catalogs) copy_translations(install_dir, QT_INSTALL_TRANSLATIONS, tr_catalogs)
if not sys.platform.startswith('win'): if not sys.platform.startswith('win'):
fix_rpaths(chrpath_bin ,install_dir) fix_rpaths(chrpath_bin, install_dir)
if __name__ == "__main__": if __name__ == "__main__":
if sys.platform == 'darwin': if sys.platform == 'darwin':

View File

@@ -18916,7 +18916,7 @@ Hinweis: Unter Umständen wird die lokale Datei gelöscht.</translation>
</message> </message>
<message> <message>
<source>Start and Debug Remote Application...</source> <source>Start and Debug Remote Application...</source>
<translation>Starte und Debugge externe Anwendung...</translation> <translation>Starte und Debugge entfernte Anwendung...</translation>
</message> </message>
<message> <message>
<source>Attach to Remote Debug Server...</source> <source>Attach to Remote Debug Server...</source>

View File

@@ -66,12 +66,13 @@ Rectangle {
Rectangle { Rectangle {
width: 1 width: 1
height: line.height height: Math.max(Math.min(recentProjects.contentHeight + 120, recentProjects.height), sessions.height)
color: "#c4c4c4" color: "#c4c4c4"
anchors.left: sessions.right anchors.left: sessions.right
anchors.leftMargin: -1 anchors.leftMargin: -1
anchors.top: sessions.top anchors.top: sessions.top
visible: !sessions.scrollBarVisible
id: sessionLine
} }
RecentProjects { RecentProjects {
@@ -96,11 +97,12 @@ Rectangle {
Rectangle { Rectangle {
id: line id: line
width: 1 width: 1
height: Math.min(recentProjects.contentHeight + 120, recentProjects.height) height: sessionLine.height
color: "#c4c4c4" color: "#c4c4c4"
anchors.left: recentProjects.right anchors.left: recentProjects.right
anchors.leftMargin: -1 anchors.leftMargin: -1
anchors.top: recentProjects.top anchors.top: recentProjects.top
visible: !recentProjects.scrollBarVisible
} }
Text { Text {

View File

@@ -34,7 +34,8 @@ import QtQuick 1.0
import qtcomponents 1.0 import qtcomponents 1.0
ScrollArea { ScrollArea {
//id: projectList property bool scrollBarVisible: projectList.verticalScrollBar.visible
id: projectList
property alias model: repeater.model property alias model: repeater.model
Behavior on verticalScrollBar.opacity { Behavior on verticalScrollBar.opacity {

View File

@@ -38,6 +38,8 @@ Item {
property int topMargin: 6 property int topMargin: 6
height: Math.min(root.contentHeight + topMargin, parent.height - 260) height: Math.min(root.contentHeight + topMargin, parent.height - 260)
property alias scrollBarVisible: vscrollbar.visible
ListView { ListView {
id: root id: root

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 B

After

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

After

Width:  |  Height:  |  Size: 261 B

View File

@@ -473,7 +473,7 @@ const Macro *Document::findMacroDefinitionAt(unsigned line) const
const Document::MacroUse *Document::findMacroUseAt(unsigned offset) const const Document::MacroUse *Document::findMacroUseAt(unsigned offset) const
{ {
foreach (const Document::MacroUse &use, _macroUses) { foreach (const Document::MacroUse &use, _macroUses) {
if (use.contains(offset)) if (use.contains(offset) && (offset < use.begin() + use.macro().name().length()))
return &use; return &use;
} }
return 0; return 0;
@@ -482,7 +482,7 @@ const Document::MacroUse *Document::findMacroUseAt(unsigned offset) const
const Document::UndefinedMacroUse *Document::findUndefinedMacroUseAt(unsigned offset) const const Document::UndefinedMacroUse *Document::findUndefinedMacroUseAt(unsigned offset) const
{ {
foreach (const Document::UndefinedMacroUse &use, _undefinedMacroUses) { foreach (const Document::UndefinedMacroUse &use, _undefinedMacroUses) {
if (use.contains(offset)) if (use.contains(offset) && (offset < use.begin() + use.name().length()))
return &use; return &use;
} }
return 0; return 0;

View File

@@ -1285,7 +1285,7 @@ CppQmlTypesLoader::BuiltinObjects CppQmlTypesLoader::loadQmlTypes(const QFileInf
if (!warning.isEmpty()) { if (!warning.isEmpty()) {
warnings->append(TypeDescriptionReader::tr( warnings->append(TypeDescriptionReader::tr(
"Warnings while loading qmltypes from %1:\n%2").arg( "Warnings while loading qmltypes from %1:\n%2").arg(
qmlTypeFile.absoluteFilePath(), error)); qmlTypeFile.absoluteFilePath(), warning));
} }
} }

View File

@@ -218,7 +218,7 @@ void TypeDescriptionReader::readComponent(UiObjectDefinition *ast)
fmo->setAttachedTypeName(readStringBinding(script)); fmo->setAttachedTypeName(readStringBinding(script));
} else { } else {
addWarning(script->firstSourceLocation(), addWarning(script->firstSourceLocation(),
"Expected only name, prototype, defaultProperty, attachedType, exports" "Expected only name, prototype, defaultProperty, attachedType, exports "
"and exportMetaObjectRevisions script bindings"); "and exportMetaObjectRevisions script bindings");
} }
} else { } else {

View File

@@ -386,28 +386,40 @@ bool BinEditor::save(QString *errorString, const QString &oldFileName, const QSt
void BinEditor::setSizes(quint64 startAddr, int range, int blockSize) void BinEditor::setSizes(quint64 startAddr, int range, int blockSize)
{ {
m_blockSize = blockSize; int newBlockSize = blockSize;
QTC_ASSERT((blockSize/m_bytesPerLine) * m_bytesPerLine == blockSize, QTC_ASSERT((blockSize/m_bytesPerLine) * m_bytesPerLine == blockSize,
blockSize = (blockSize/m_bytesPerLine + 1) * m_bytesPerLine); blockSize = (blockSize/m_bytesPerLine + 1) * m_bytesPerLine);
// Users can edit data in the range
// [startAddr - range/2, startAddr + range/2].
quint64 newBaseAddr = quint64(range/2) > startAddr ? 0 : startAddr - range/2;
newBaseAddr = (newBaseAddr / blockSize) * blockSize;
const quint64 maxRange = Q_UINT64_C(0xffffffffffffffff) - newBaseAddr + 1;
int newSize = newBaseAddr != 0 && quint64(range) >= maxRange
? maxRange : range;
int newAddressBytes = (newBaseAddr + newSize < quint64(1) << 32
&& newBaseAddr + newSize >= newBaseAddr) ? 4 : 8;
if (newBlockSize == m_blockSize
&& newBaseAddr == m_baseAddr
&& newSize == m_size
&& newAddressBytes == m_addressBytes)
return;
m_blockSize = blockSize;
m_emptyBlock = QByteArray(blockSize, '\0'); m_emptyBlock = QByteArray(blockSize, '\0');
m_modifiedData.clear(); m_modifiedData.clear();
m_requests.clear(); m_requests.clear();
// Users can edit data in the range m_baseAddr = newBaseAddr;
// [startAddr - range/2, startAddr + range/2]. m_size = newSize;
m_baseAddr = quint64(range/2) > startAddr ? 0 : startAddr - range/2; m_addressBytes = newAddressBytes;
m_baseAddr = (m_baseAddr / blockSize) * blockSize;
const quint64 maxRange = Q_UINT64_C(0xffffffffffffffff) - m_baseAddr + 1;
m_size = m_baseAddr != 0 && quint64(range) >= maxRange
? maxRange : range;
m_addressBytes = (m_baseAddr + m_size < quint64(1) << 32
&& m_baseAddr + m_size >= m_baseAddr) ? 4 : 8;
m_unmodifiedState = 0; m_unmodifiedState = 0;
m_undoStack.clear(); m_undoStack.clear();
m_redoStack.clear(); m_redoStack.clear();
init(); init();
setCursorPosition(startAddr - m_baseAddr); setCursorPosition(startAddr - m_baseAddr);

View File

@@ -234,10 +234,10 @@ public:
if (offset >= static_cast<quint64>(file.size())) if (offset >= static_cast<quint64>(file.size()))
return false; return false;
if (file.open(QIODevice::ReadOnly)) { if (file.open(QIODevice::ReadOnly)) {
file.close();
m_fileName = fileName; m_fileName = fileName;
m_editor->setSizes(offset, file.size()); m_editor->setSizes(offset, file.size());
m_editor->editor()->setDisplayName(QFileInfo(fileName).fileName()); m_editor->editor()->setDisplayName(QFileInfo(fileName).fileName());
file.close();
return true; return true;
} }
QString errStr = tr("Cannot open %1: %2").arg( QString errStr = tr("Cannot open %1: %2").arg(
@@ -258,11 +258,11 @@ private slots:
int blockSize = m_editor->dataBlockSize(); int blockSize = m_editor->dataBlockSize();
file.seek(block * blockSize); file.seek(block * blockSize);
QByteArray data = file.read(blockSize); QByteArray data = file.read(blockSize);
file.close();
const int dataSize = data.size(); const int dataSize = data.size();
if (dataSize != blockSize) if (dataSize != blockSize)
data += QByteArray(blockSize - dataSize, 0); data += QByteArray(blockSize - dataSize, 0);
m_editor->addData(block, data); m_editor->addData(block, data);
file.close();
} else { } else {
QMessageBox::critical(Core::ICore::mainWindow(), tr("File Error"), QMessageBox::critical(Core::ICore::mainWindow(), tr("File Error"),
tr("Cannot open %1: %2").arg( tr("Cannot open %1: %2").arg(

View File

@@ -253,7 +253,7 @@ void CodepasterPlugin::post(QString data, const QString &mimeType)
const QString username = m_settings->username; const QString username = m_settings->username;
PasteView view(m_protocols, mimeType, 0); PasteView view(m_protocols, mimeType, ICore::mainWindow());
view.setProtocol(m_settings->protocol); view.setProtocol(m_settings->protocol);
const FileDataList diffChunks = splitDiffToFiles(data); const FileDataList diffChunks = splitDiffToFiles(data);

View File

@@ -707,11 +707,14 @@ const Macro *CPPEditorWidget::findCanonicalMacro(const QTextCursor &cursor, Docu
int line, col; int line, col;
convertPosition(cursor.position(), &line, &col); convertPosition(cursor.position(), &line, &col);
if (const Macro *macro = doc->findMacroDefinitionAt(line)) if (const Macro *macro = doc->findMacroDefinitionAt(line)) {
return macro; QTextCursor macroCursor = cursor;
const QByteArray name = identifierUnderCursor(&macroCursor).toLatin1();
if (const Document::MacroUse *use = doc->findMacroUseAt(cursor.position())) if (macro->name() == name)
return macro;
} else if (const Document::MacroUse *use = doc->findMacroUseAt(cursor.position())) {
return &use->macro(); return &use->macro();
}
return 0; return 0;
} }
@@ -722,12 +725,13 @@ void CPPEditorWidget::findUsages()
info.snapshot = CppModelManagerInterface::instance()->snapshot(); info.snapshot = CppModelManagerInterface::instance()->snapshot();
info.snapshot.insert(info.doc); info.snapshot.insert(info.doc);
CanonicalSymbol cs(this, info); if (const Macro *macro = findCanonicalMacro(textCursor(), info.doc)) {
Symbol *canonicalSymbol = cs(textCursor());
if (canonicalSymbol) {
m_modelManager->findUsages(canonicalSymbol, cs.context());
} else if (const Macro *macro = findCanonicalMacro(textCursor(), info.doc)) {
m_modelManager->findMacroUsages(*macro); m_modelManager->findMacroUsages(*macro);
} else {
CanonicalSymbol cs(this, info);
Symbol *canonicalSymbol = cs(textCursor());
if (canonicalSymbol)
m_modelManager->findUsages(canonicalSymbol, cs.context());
} }
} }
@@ -1381,6 +1385,25 @@ CPPEditorWidget::Link CPPEditorWidget::findLinkAt(const QTextCursor &cursor,
tc.setPosition(endOfToken); tc.setPosition(endOfToken);
} }
// Handle macro uses
const Macro *macro = doc->findMacroDefinitionAt(line);
if (macro) {
QTextCursor macroCursor = cursor;
const QByteArray name = identifierUnderCursor(&macroCursor).toLatin1();
if (macro->name() == name)
return link; //already on definition!
} else {
const Document::MacroUse *use = doc->findMacroUseAt(endOfToken - 1);
if (use && use->macro().fileName() != QLatin1String("<configuration>")) {
const Macro &macro = use->macro();
link.fileName = macro.fileName();
link.line = macro.line();
link.begin = use->begin();
link.end = use->end();
return link;
}
}
// Find the last symbol up to the cursor position // Find the last symbol up to the cursor position
Scope *scope = doc->scopeAt(line, column); Scope *scope = doc->scopeAt(line, column);
if (!scope) if (!scope)

View File

@@ -198,6 +198,26 @@ bool CppAssistProposalItem::prematurelyApplies(const QChar &typedChar) const
return false; return false;
} }
static bool isDereferenced(TextEditor::BaseTextEditor *editor, int basePosition)
{
QTextCursor cursor = editor->editorWidget()->textCursor();
cursor.setPosition(basePosition);
BackwardsScanner scanner(cursor);
for (int pos = scanner.startToken()-1; pos >= 0; pos--) {
switch (scanner[pos].kind()) {
case T_COLON_COLON:
case T_IDENTIFIER:
//Ignore scope specifiers
break;
case T_AMPER: return true;
default: return false;
}
}
return false;
}
void CppAssistProposalItem::applyContextualContent(TextEditor::BaseTextEditor *editor, void CppAssistProposalItem::applyContextualContent(TextEditor::BaseTextEditor *editor,
int basePosition) const int basePosition) const
{ {
@@ -249,7 +269,7 @@ void CppAssistProposalItem::applyContextualContent(TextEditor::BaseTextEditor *e
extraChars += QLatin1Char('<'); extraChars += QLatin1Char('<');
} }
#endif #endif
} else if (! function->isAmbiguous()) { } else if (!isDereferenced(editor, basePosition) && ! function->isAmbiguous()) {
// When the user typed the opening parenthesis, he'll likely also type the closing one, // When the user typed the opening parenthesis, he'll likely also type the closing one,
// in which case it would be annoying if we put the cursor after the already automatically // in which case it would be annoying if we put the cursor after the already automatically
// inserted closing parenthesis. // inserted closing parenthesis.

View File

@@ -83,10 +83,11 @@ bool isIntType(const QByteArray &type)
case 'c': case 'c':
return type == "char"; return type == "char";
case 'i': case 'i':
return type == "int" || type == "int64"; return type == "int";
case 'l': case 'l':
return type == "long" return type == "long"
|| type.startsWith("long "); || type == "long int"
|| type == "long unsigned int";
case 'p': case 'p':
return type == "ptrdiff_t"; return type == "ptrdiff_t";
case 'q': case 'q':
@@ -100,10 +101,24 @@ bool isIntType(const QByteArray &type)
|| type == "size_t" || type == "size_t"
|| type == "std::size_t" || type == "std::size_t"
|| type == "std::ptrdiff_t" || type == "std::ptrdiff_t"
|| type.startsWith("signed "); || (type.startsWith("signed") &&
( type == "signed char"
|| type == "signed short"
|| type == "signed short int"
|| type == "signed long"
|| type == "signed long int"
|| type == "signed long long"
|| type == "signed long long int"));
case 'u': case 'u':
return type == "unsigned" return type == "unsigned"
|| type.startsWith("unsigned "); || (type.startsWith("unsigned") &&
( type == "unsigned char"
|| type == "unsigned short"
|| type == "unsigned short int"
|| type == "unsigned long"
|| type == "unsigned long int"
|| type == "unsigned long long"
|| type == "unsigned long long int"));
default: default:
return false; return false;
} }

View File

@@ -378,8 +378,9 @@ static QString reformatCharacter(int code, int format)
const QString codeS = reformatInteger(code, format); const QString codeS = reformatInteger(code, format);
if (code < 0) // Append unsigned value. if (code < 0) // Append unsigned value.
return codeS + QLatin1String(" / ") + reformatInteger(256 + code, format); return codeS + QLatin1String(" / ") + reformatInteger(256 + code, format);
if (code >= 32 && code < 128) const QChar c = QLatin1Char(code);
return codeS + QLatin1String(" '") + QChar(code) + QLatin1Char('\''); if (c.isPrint())
return codeS + QLatin1String(" '") + c + QLatin1Char('\'');
switch (code) { switch (code) {
case 0: case 0:
return codeS + QLatin1String(" '\\0'"); return codeS + QLatin1String(" '\\0'");
@@ -402,7 +403,7 @@ static QString quoteUnprintable(const QString &str)
if (WatchHandler::unprintableBase() == -1) { if (WatchHandler::unprintableBase() == -1) {
foreach (const QChar c, str) { foreach (const QChar c, str) {
int u = c.unicode(); int u = c.unicode();
if (u >= 32 && u < 127) if (c.isPrint())
encoded += c; encoded += c;
else if (u == '\r') else if (u == '\r')
encoded += QLatin1String("\\r"); encoded += QLatin1String("\\r");
@@ -473,9 +474,6 @@ QString WatchModel::formattedValue(const WatchData &data) const
return value; return value;
} }
const QByteArray qtNamespace = engine()->qtNamespace();
int format = itemFormat(data);
if (isIntType(data.type)) { if (isIntType(data.type)) {
if (value.isEmpty()) if (value.isEmpty())
return value; return value;
@@ -483,7 +481,9 @@ QString WatchModel::formattedValue(const WatchData &data) const
const QChar firstChar = value.at(0); const QChar firstChar = value.at(0);
if (!firstChar.isDigit() && firstChar != QLatin1Char('-')) if (!firstChar.isDigit() && firstChar != QLatin1Char('-'))
return value; return value;
// Append quoted, printable character also for decimal. // Append quoted, printable character also for decimal.
const int format = itemFormat(data);
if (data.type.endsWith("char")) { if (data.type.endsWith("char")) {
bool ok; bool ok;
const int code = value.toInt(&ok); const int code = value.toInt(&ok);
@@ -504,8 +504,10 @@ QString WatchModel::formattedValue(const WatchData &data) const
if (!isPointerType(data.type) && !data.isVTablePointer()) { if (!isPointerType(data.type) && !data.isVTablePointer()) {
bool ok = false; bool ok = false;
qulonglong integer = value.toULongLong(&ok, 0); qulonglong integer = value.toULongLong(&ok, 0);
if (ok) if (ok) {
return reformatInteger(integer, format); const int format = itemFormat(data);
return reformatInteger(integer, format);
}
} }
return translate(value); return translate(value);
@@ -1087,8 +1089,9 @@ void WatchModel::insertData(const WatchData &data)
if (WatchItem *oldItem = findItem(data.iname, parent)) { if (WatchItem *oldItem = findItem(data.iname, parent)) {
bool hadChildren = oldItem->hasChildren; bool hadChildren = oldItem->hasChildren;
// Overwrite old entry. // Overwrite old entry.
bool hasChanged = oldItem->hasChanged(data);
oldItem->setData(data); oldItem->setData(data);
oldItem->changed = data.hasChanged(*oldItem); oldItem->changed = hasChanged;
oldItem->generation = m_generationCounter; oldItem->generation = m_generationCounter;
QModelIndex idx = watchIndex(oldItem); QModelIndex idx = watchIndex(oldItem);
emit dataChanged(idx, idx.sibling(idx.row(), 2)); emit dataChanged(idx, idx.sibling(idx.row(), 2));

View File

@@ -631,8 +631,6 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
mi0.data(LocalsTypeFormatRole).toInt(); mi0.data(LocalsTypeFormatRole).toInt();
const int individualFormat = const int individualFormat =
mi0.data(LocalsIndividualFormatRole).toInt(); mi0.data(LocalsIndividualFormatRole).toInt();
const int effectiveIndividualFormat =
individualFormat == -1 ? typeFormat : individualFormat;
const int unprintableBase = handler->unprintableBase(); const int unprintableBase = handler->unprintableBase();
QMenu formatMenu; QMenu formatMenu;
@@ -667,16 +665,18 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
QAction *dummy = formatMenu.addAction( QAction *dummy = formatMenu.addAction(
tr("Change Display for Object Named \"%1\":").arg(mi0.data().toString())); tr("Change Display for Object Named \"%1\":").arg(mi0.data().toString()));
dummy->setEnabled(false); dummy->setEnabled(false);
clearIndividualFormatAction QString msg = (individualFormat == -1 && typeFormat != -1)
= formatMenu.addAction(spacer + tr("Use Display Format Based on Type")); ? tr("Use Format for Type (Currently %1)")
//clearIndividualFormatAction->setEnabled(individualFormat != -1); .arg(alternativeFormats.at(typeFormat))
: tr("Use Display Format Based on Type ");
clearIndividualFormatAction = formatMenu.addAction(spacer + msg);
clearIndividualFormatAction->setCheckable(true); clearIndividualFormatAction->setCheckable(true);
clearIndividualFormatAction->setChecked(effectiveIndividualFormat == -1); clearIndividualFormatAction->setChecked(individualFormat == -1);
for (int i = 0; i != alternativeFormats.size(); ++i) { for (int i = 0; i != alternativeFormats.size(); ++i) {
const QString format = spacer + alternativeFormats.at(i); const QString format = spacer + alternativeFormats.at(i);
QAction *act = new QAction(format, &formatMenu); QAction *act = new QAction(format, &formatMenu);
act->setCheckable(true); act->setCheckable(true);
if (i == effectiveIndividualFormat) if (i == individualFormat)
act->setChecked(true); act->setChecked(true);
formatMenu.addAction(act); formatMenu.addAction(act);
individualFormatActions.append(act); individualFormatActions.append(act);

View File

@@ -83,8 +83,14 @@ QSharedPointer<VcsBase::AbstractCheckoutJob> CloneWizard::createJob(const QList<
QString *checkoutPath) QString *checkoutPath)
{ {
// Collect parameters for the clone command. // Collect parameters for the clone command.
const CloneWizardPage *cwp = qobject_cast<const CloneWizardPage *>(parameterPages.front()); const CloneWizardPage *cwp = 0;
QTC_ASSERT(cwp, return QSharedPointer<VcsBase::AbstractCheckoutJob>()) foreach (QWizardPage *wp, parameterPages) {
cwp = qobject_cast<const CloneWizardPage *>(wp);
if (cwp)
break;
}
QTC_ASSERT(cwp, return QSharedPointer<VcsBase::AbstractCheckoutJob>());
return cwp->createCheckoutJob(checkoutPath); return cwp->createCheckoutJob(checkoutPath);
} }

View File

@@ -89,6 +89,8 @@ bool ImageViewerFile::save(QString *errorString, const QString &fileName, bool a
void ImageViewerFile::rename(const QString &newName) void ImageViewerFile::rename(const QString &newName)
{ {
d->fileName = newName; d->fileName = newName;
d->editor->setDisplayName(QFileInfo(d->fileName).fileName());
emit changed();
} }
QString ImageViewerFile::fileName() const QString ImageViewerFile::fileName() const

View File

@@ -546,21 +546,24 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect()
if (folder.isEmpty()) if (folder.isEmpty())
continue; continue;
const QString sdkVcVarsBat = folder + QLatin1String("bin\\SetEnv.cmd"); QDir dir(folder);
if (!QFileInfo(sdkVcVarsBat).exists()) if (!dir.cd(QLatin1String("bin")))
continue;
QFileInfo fi(dir, QLatin1String("SetEnv.cmd"));
if (!fi.exists())
continue; continue;
QList<ToolChain *> tmp;
QList<ToolChain *> tmp;
tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::s32), tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::s32),
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::s32, version), findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::s32, version),
sdkVcVarsBat, QLatin1String("/x86"), true)); fi.absoluteFilePath(), QLatin1String("/x86"), true));
// Add all platforms // Add all platforms
tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::s64), tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::s64),
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::s64, version), findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::s64, version),
sdkVcVarsBat, QLatin1String("/x64"), true)); fi.absoluteFilePath(), QLatin1String("/x64"), true));
tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::ia64), tmp.append(new MsvcToolChain(generateDisplayName(name, MsvcToolChain::WindowsSDK, MsvcToolChain::ia64),
findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::ia64, version), findAbiOfMsvc(MsvcToolChain::WindowsSDK, MsvcToolChain::ia64, version),
sdkVcVarsBat, QLatin1String("/ia64"), true)); fi.absoluteFilePath(), QLatin1String("/ia64"), true));
// Make sure the default is front. // Make sure the default is front.
if (folder == defaultSdkPath) if (folder == defaultSdkPath)
results = tmp + results; results = tmp + results;

View File

@@ -257,6 +257,11 @@ Qt4PriFileNode::Qt4PriFileNode(Qt4Project *project, Qt4ProFileNode* qt4ProFileNo
setIcon(qt4NodeStaticData()->projectIcon); setIcon(qt4NodeStaticData()->projectIcon);
} }
Qt4PriFileNode::~Qt4PriFileNode()
{
watchFolders(QSet<QString>());
}
void Qt4PriFileNode::scheduleUpdate() void Qt4PriFileNode::scheduleUpdate()
{ {
QtSupport::ProFileCacheManager::instance()->discardFile(m_projectFilePath); QtSupport::ProFileCacheManager::instance()->discardFile(m_projectFilePath);

View File

@@ -129,6 +129,7 @@ class QT4PROJECTMANAGER_EXPORT Qt4PriFileNode : public ProjectExplorer::ProjectN
public: public:
Qt4PriFileNode(Qt4Project *project, Qt4ProFileNode* qt4ProFileNode, const QString &filePath); Qt4PriFileNode(Qt4Project *project, Qt4ProFileNode* qt4ProFileNode, const QString &filePath);
~Qt4PriFileNode();
void update(ProFile *includeFileExact, QtSupport::ProFileReader *readerExact, ProFile *includeFileCumlative, QtSupport::ProFileReader *readerCumalative); void update(ProFile *includeFileExact, QtSupport::ProFileReader *readerExact, ProFile *includeFileCumlative, QtSupport::ProFileReader *readerCumalative);

View File

@@ -201,7 +201,7 @@ void Qt4Manager::updateVariable(const QByteArray &variable)
return; return;
} }
QString value; QString value;
QtSupport::BaseQtVersion *qtv; const QtSupport::BaseQtVersion *qtv = 0;
if (Qt4BaseTarget *t = qt4pro->activeTarget()) { if (Qt4BaseTarget *t = qt4pro->activeTarget()) {
if (Qt4BuildConfiguration *bc = t->activeQt4BuildConfiguration()) if (Qt4BuildConfiguration *bc = t->activeQt4BuildConfiguration())
qtv = bc->qtVersion(); qtv = bc->qtVersion();

View File

@@ -84,7 +84,7 @@ bool DocumentMarker::addMark(TextEditor::ITextMark *mark)
userData->addMark(mark); userData->addMark(mark);
m_marksCache.append(mark); m_marksCache.append(mark);
mark->updateLineNumber(blockNumber + 1); mark->updateLineNumber(blockNumber + 1);
QTC_CHECK(mark->lineNumber() == blockNumber + 1); QTC_CHECK(mark->lineNumber() == blockNumber + 1); // Checks that the base class is called
mark->updateBlock(block); mark->updateBlock(block);
documentLayout->hasMarks = true; documentLayout->hasMarks = true;
documentLayout->maxMarkWidthFactor = qMax(mark->widthFactor(), documentLayout->maxMarkWidthFactor = qMax(mark->widthFactor(),
@@ -716,14 +716,14 @@ void BaseTextDocumentLayout::documentClosing()
void BaseTextDocumentLayout::updateMarksLineNumber() void BaseTextDocumentLayout::updateMarksLineNumber()
{ {
// Note: the breakpointmanger deletes breakpoint marks and readds them
// if it doesn't agree with our updating
QTextBlock block = document()->begin(); QTextBlock block = document()->begin();
int blockNumber = 0; int blockNumber = 0;
while (block.isValid()) { while (block.isValid()) {
if (const TextBlockUserData *userData = testUserData(block)) if (const TextBlockUserData *userData = testUserData(block))
foreach (ITextMark *mrk, userData->marks()) { foreach (ITextMark *mrk, userData->marks())
mrk->updateLineNumber(blockNumber + 1); mrk->updateLineNumber(blockNumber + 1);
QTC_CHECK(mrk->lineNumber() == blockNumber +1);
}
block = block.next(); block = block.next();
++blockNumber; ++blockNumber;
} }

View File

@@ -219,8 +219,7 @@ QString BaseCheckoutWizard::openProject(const QString &path, QString *errorMessa
void BaseCheckoutWizard::slotProgressPageShown() void BaseCheckoutWizard::slotProgressPageShown()
{ {
const QSharedPointer<AbstractCheckoutJob> job = createJob(d->parameterPages, &(d->checkoutPath)); const QSharedPointer<AbstractCheckoutJob> job = createJob(d->parameterPages, &(d->checkoutPath));
if (!job.isNull()) d->dialog->start(job);
d->dialog->start(job);
} }
} // namespace VcsBase } // namespace VcsBase

View File

@@ -69,6 +69,11 @@ CheckoutProgressWizardPage::~CheckoutProgressWizardPage()
void CheckoutProgressWizardPage::start(const QSharedPointer<AbstractCheckoutJob> &job) void CheckoutProgressWizardPage::start(const QSharedPointer<AbstractCheckoutJob> &job)
{ {
if (job.isNull()) {
ui->logPlainTextEdit->setPlainText(tr("No job running, please abort."));
return;
}
QTC_ASSERT(m_state != Running, return) QTC_ASSERT(m_state != Running, return)
m_job = job; m_job = job;
connect(job.data(), SIGNAL(output(QString)), ui->logPlainTextEdit, SLOT(appendPlainText(QString))); connect(job.data(), SIGNAL(output(QString)), ui->logPlainTextEdit, SLOT(appendPlainText(QString)));