diff options
Diffstat (limited to 'share')
87 files changed, 1443 insertions, 516 deletions
diff --git a/share/qtcreator/CMakeLists.txt b/share/qtcreator/CMakeLists.txt index 3fe6c60b4b..63393293c1 100644 --- a/share/qtcreator/CMakeLists.txt +++ b/share/qtcreator/CMakeLists.txt @@ -1,5 +1,5 @@ set(template_directories cplusplus debugger glsl modeleditor qml qmldesigner - qmlicons qml-type-descriptions schemes snippets styles templates themes welcomescreen) + qmlicons qml-type-descriptions schemes scripts snippets styles templates themes welcomescreen) add_custom_target(copy_share_to_builddir ALL COMMENT Copy files into build directory @@ -21,3 +21,5 @@ install( FILES indexer_preincludes/qglobal.h indexer_preincludes/windows.h DESTINATION "${IDE_DATA_PATH}/indexer_preincludes" ) + +add_subdirectory(translations) diff --git a/share/qtcreator/cplusplus/examples/CMakeLists.txt b/share/qtcreator/cplusplus/examples/CMakeLists.txt new file mode 100644 index 0000000000..2a5aeb6d78 --- /dev/null +++ b/share/qtcreator/cplusplus/examples/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.5) + +project(examples LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt5 COMPONENTS Widgets REQUIRED) + +add_executable(examples + clazy_example.cpp + tidy_example.cpp + tidy_example.h +) + +target_link_libraries(examples PRIVATE Qt5::Widgets) diff --git a/share/qtcreator/debugger/.pylintrc b/share/qtcreator/debugger/.pylintrc new file mode 100644 index 0000000000..dabd2ee07a --- /dev/null +++ b/share/qtcreator/debugger/.pylintrc @@ -0,0 +1,11 @@ +[MESSAGES CONTROL] +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time. +#enable= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). +disable=invalid-name,missing-docstring diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index aa351b7e7e..04969d8e32 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -407,6 +407,8 @@ class DumperBase: return xrange(min(self.currentMaxNumChild, self.currentNumChild)) def enterSubItem(self, item): + if self.useTimeStamps: + item.startTime = time.time() if not item.iname: item.iname = '%s.%s' % (self.currentIName, item.name) if not self.isCli: @@ -424,8 +426,6 @@ class DumperBase: self.currentIName = item.iname self.currentValue = ReportItem(); self.currentType = ReportItem(); - if self.useTimeStamps: - item.startTime = time.time() def exitSubItem(self, item, exType, exValue, exTraceBack): #warn('CURRENT VALUE: %s: %s %s' % @@ -435,8 +435,6 @@ class DumperBase: showException('SUBITEM', exType, exValue, exTraceBack) self.putSpecialValue('notaccessible') self.putNumChild(0) - if self.useTimeStamps: - self.put('time="%s",' % (time.time() - item.startTime)) if not self.isCli: try: if self.currentType.value: @@ -453,6 +451,8 @@ class DumperBase: self.put('value="%s",' % self.currentValue.value) except: pass + if self.useTimeStamps: + self.put('time="%s",' % (time.time() - item.startTime)) self.put('},') else: self.indent -= 1 diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 27d33e3046..34589e0dd8 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -1910,7 +1910,7 @@ class LogMixin: localz = frame.f_locals instance = str(localz["self"]) + "." if 'self' in localz else '' message = "%s%s(%s)%s" % (instance, fn, args, message) - print message + print(message) @staticmethod def log_fn(arg_str = ''): @@ -1945,7 +1945,7 @@ class SummaryDumper(Dumper, LogMixin): @staticmethod def warn(message): - print "Qt summary warning: %s" % message + print("Qt summary warning: %s" % message) @staticmethod def showException(message, exType, exValue, exTraceback): @@ -1979,9 +1979,9 @@ class SummaryDumper(Dumper, LogMixin): try: from pygdbmi import gdbmiparser except ImportError: - print "Qt summary provider requires the pygdbmi module, " \ - "please install using 'sudo /usr/bin/easy_install pygdbmi', " \ - "and then restart Xcode." + print("Qt summary provider requires the pygdbmi module, " + "please install using 'sudo /usr/bin/easy_install pygdbmi', " + "and then restart Xcode.") lldb.debugger.HandleCommand('type category delete Qt') return None diff --git a/share/qtcreator/debugger/misctypes.py b/share/qtcreator/debugger/misctypes.py index 97b2f6ef63..72e42e4510 100644 --- a/share/qtcreator/debugger/misctypes.py +++ b/share/qtcreator/debugger/misctypes.py @@ -181,6 +181,7 @@ def qdump__Eigen__Matrix(d, value): def qdump__NimStringDesc(d, value): size, reserved = value.split('pp') data = value.address() + 2 * d.ptrSize() + d.putBetterType('string') d.putCharArrayHelper(data, size, d.createType('char'), 'utf8') def qdump__NimGenericSequence__(d, value, regex = '^TY[\d]+$'): diff --git a/share/qtcreator/debugger/pdbbridge.py b/share/qtcreator/debugger/pdbbridge.py index 76e213507d..fd9bef48cb 100644 --- a/share/qtcreator/debugger/pdbbridge.py +++ b/share/qtcreator/debugger/pdbbridge.py @@ -26,22 +26,22 @@ import os import re import sys -import dis import code -import glob import base64 +import linecache import signal import string import inspect import traceback -import linecache import fnmatch import platform + class QuitException(Exception): pass -class Breakpoint: + +class QtcInternalBreakpoint: """Breakpoint class. Breakpoints are indexed by number through bpbynumber and by the file,line tuple using bplist. The former points to a @@ -56,25 +56,25 @@ class Breakpoint: # index 0 is unused, except for marking an # effective break .... see effective() - def __init__(self, file, line, temporary=False, cond=None, funcname=None): + def __init__(self, filepath, line, temporary=False, cond=None, funcname=None): self.funcname = funcname # Needed if funcname is not None. self.func_first_executable_line = None - self.file = file # This better be in canonical form! + self.file = filepath # This better be in canonical form! self.line = line self.temporary = temporary self.cond = cond self.enabled = True self.ignore = 0 self.hits = 0 - self.number = Breakpoint.next - Breakpoint.next += 1 + self.number = QtcInternalBreakpoint.next + QtcInternalBreakpoint.next += 1 # Build the two lists self.bpbynumber.append(self) - if (file, line) in self.bplist: - self.bplist[file, line].append(self) + if (filepath, line) in self.bplist: + self.bplist[filepath, line].append(self) else: - self.bplist[file, line] = [self] + self.bplist[filepath, line] = [self] def deleteMe(self): index = (self.file, self.line) @@ -120,9 +120,10 @@ def checkfuncname(b, frame): return False return True + # Determines if there is an effective (active) breakpoint at this # line of code. Returns breakpoint number or 0 if none -def effective(file, line, frame): +def effective(filename, line, frame): """Determine which breakpoint for this file:line is to be acted upon. Called only if we know there is a bpt at this @@ -130,7 +131,7 @@ def effective(file, line, frame): that indicates if it is ok to delete a temporary bp. """ - possibles = Breakpoint.bplist[file, line] + possibles = QtcInternalBreakpoint.bplist[filename, line] for b in possibles: if not b.enabled: continue @@ -168,8 +169,8 @@ def effective(file, line, frame): return (None, None) +# __all__ = ['QtcInternalDumper'] -#__all__ = ['Dumper'] def find_function(funcname, filename): cre = re.compile(r'def\s+%s\s*[(]' % re.escape(funcname)) @@ -184,18 +185,21 @@ def find_function(funcname, filename): return funcname, filename, lineno return None + class _rstr(str): """String that doesn't quote its repr.""" + def __repr__(self): return self -class Dumper: + +class QtcInternalDumper: identchars = string.ascii_letters + string.digits + '_' lastcmd = '' use_rawinput = 1 def __init__(self, stdin=None, stdout=None): - self.skip = None + self.skip = [] self.breaks = {} self.fncache = {} self.frame_returning = None @@ -227,21 +231,47 @@ class Dumper: self.allow_kbdint = False self.nosigint = nosigint - self.commands = {} # associates a command list to breakpoint numbers + self.commands = {} # associates a command list to breakpoint numbers + self.botframe = None + self.currentbp = -1 + self.stopframe = None + self.returnframe = None + self.quitting = False + self.stoplineno = 0 + self.mainpyfile = '' + self._user_requested_quit = False + self.stack = [] + self.curindex = 0 + self.curframe = None + self.curframe_locals = {} + self.typeformats = {} + self.formats = {} + self.output = '' + self.expandedINames = [] # Hex decoding operating on str, return str. - def hexdecode(self, s): + @staticmethod + def hexdecode(s): if sys.version_info[0] == 2: return s.decode('hex') return bytes.fromhex(s).decode('utf8') # Hex encoding operating on str or bytes, return str. - def hexencode(self, s): + @staticmethod + def hexencode(s): if sys.version_info[0] == 2: return s.encode('hex') if isinstance(s, str): s = s.encode('utf8') return base64.b16encode(s).decode('utf8') + + @staticmethod + def cleanAddress(addr): + if addr is None: + return '<no address>' + h = hex(addr) + return '0x%x' % (int(h, 16) if sys.version_info[0] >= 3 else long(h, 16)) + def canonic(self, filename): if filename == '<' + filename[1:-1] + '>': return filename @@ -255,7 +285,6 @@ class Dumper: return canonic def reset(self): - import linecache linecache.checkcache() self.botframe = None self._set_stopinfo(None, None) @@ -263,7 +292,7 @@ class Dumper: def trace_dispatch(self, frame, event, arg): if self.quitting: - return # None + return None if event == 'line': return self.dispatch_line(frame) if event == 'call': @@ -284,22 +313,24 @@ class Dumper: def dispatch_line(self, frame): if self.stop_here(frame) or self.break_here(frame): self.user_line(frame) - if self.quitting: raise QuitException + if self.quitting: + raise QuitException return self.trace_dispatch def dispatch_call(self, frame): if self.botframe is None: # First call of dispatch since reset() - self.botframe = frame.f_back # (CT) Note that this may also be None! + self.botframe = frame.f_back # (CT) Note that this may also be None! return self.trace_dispatch if not (self.stop_here(frame) or self.break_anywhere(frame)): # No need to trace this function - return # None + return None # Ignore call events in generator except when stepping. if self.stopframe and frame.f_code.co_flags & inspect.CO_GENERATOR: return self.trace_dispatch self.user_call(frame) - if self.quitting: raise QuitException + if self.quitting: + raise QuitException return self.trace_dispatch def dispatch_return(self, frame, arg): @@ -312,7 +343,8 @@ class Dumper: self.user_return(frame, arg) finally: self.frame_returning = None - if self.quitting: raise QuitException + if self.quitting: + raise QuitException # The user issued a 'next' or 'until' command. if self.stopframe is frame and self.stoplineno != -1: self._set_stopinfo(None, None) @@ -326,16 +358,18 @@ class Dumper: if not (frame.f_code.co_flags & inspect.CO_GENERATOR and arg[0] is StopIteration and arg[2] is None): self.user_exception(frame, arg) - if self.quitting: raise QuitException + if self.quitting: + raise QuitException # Stop at the StopIteration or GeneratorExit exception when the user # has set stopframe in a generator by issuing a return command, or a # next/until command at the last statement in the generator before the # exception. elif (self.stopframe and frame is not self.stopframe - and self.stopframe.f_code.co_flags & inspect.CO_GENERATOR - and arg[0] in (StopIteration, GeneratorExit)): + and self.stopframe.f_code.co_flags & inspect.CO_GENERATOR + and arg[0] in (StopIteration, GeneratorExit)): self.user_exception(frame, arg) - if self.quitting: raise QuitException + if self.quitting: + raise QuitException return self.trace_dispatch @@ -453,17 +487,17 @@ class Dumper: def set_break(self, filename, lineno, temporary=False, cond=None, funcname=None): filename = self.canonic(filename) - import linecache # Import as late as possible line = linecache.getline(filename, lineno) if not line: return 'Line %s:%d does not exist' % (filename, lineno) - list = self.breaks.setdefault(filename, []) - if lineno not in list: - list.append(lineno) - bp = Breakpoint(filename, lineno, temporary, cond, funcname) + lines = self.breaks.setdefault(filename, []) + if lineno not in lines: + lines.append(lineno) + QtcInternalBreakpoint(filename, lineno, temporary, cond, funcname) + return None def _prune_breaks(self, filename, lineno): - if (filename, lineno) not in Breakpoint.bplist: + if (filename, lineno) not in QtcInternalBreakpoint.bplist: self.breaks[filename].remove(lineno) if not self.breaks[filename]: del self.breaks[filename] @@ -476,9 +510,10 @@ class Dumper: return 'There is no breakpoint at %s:%d' % (filename, lineno) # If there's only one bp in the list for that file,line # pair, then remove the breaks entry - for bp in Breakpoint.bplist[filename, lineno][:]: + for bp in QtcInternalBreakpoint.bplist[filename, lineno][:]: bp.deleteMe() self._prune_breaks(filename, lineno) + return None def clear_bpbynumber(self, arg): try: @@ -487,26 +522,28 @@ class Dumper: return str(err) bp.deleteMe() self._prune_breaks(bp.file, bp.line) + return None def clear_all_file_breaks(self, filename): filename = self.canonic(filename) if filename not in self.breaks: - return 'There are no breakpoints in %s' % filename + return for line in self.breaks[filename]: - blist = Breakpoint.bplist[filename, line] + blist = QtcInternalBreakpoint.bplist[filename, line] for bp in blist: bp.deleteMe() del self.breaks[filename] def clear_all_breaks(self): if not self.breaks: - return 'There are no breakpoints' - for bp in Breakpoint.bpbynumber: + return + for bp in QtcInternalBreakpoint.bpbynumber: if bp: bp.deleteMe() self.breaks = {} - def get_bpbynumber(self, arg): + @staticmethod + def get_bpbynumber(arg): if not arg: raise ValueError('Breakpoint number expected') try: @@ -514,7 +551,7 @@ class Dumper: except ValueError: raise ValueError('Non-numeric breakpoint number %s' % arg) try: - bp = Breakpoint.bpbynumber[number] + bp = QtcInternalBreakpoint.bpbynumber[number] except IndexError: raise ValueError('Breakpoint number %d out of range' % number) if bp is None: @@ -528,16 +565,11 @@ class Dumper: def get_breaks(self, filename, lineno): filename = self.canonic(filename) - return filename in self.breaks and \ - lineno in self.breaks[filename] and \ - Breakpoint.bplist[filename, lineno] or [] + return QtcInternalBreakpoint.bplist.get((filename, lineno), []) def get_file_breaks(self, filename): filename = self.canonic(filename) - if filename in self.breaks: - return self.breaks[filename] - else: - return [] + return self.breaks.get(filename, []) def get_all_breaks(self): return self.breaks @@ -545,21 +577,21 @@ class Dumper: # Derived classes and clients can call the following method # to get a data structure representing a stack trace. - def get_stack(self, f, t): + def get_stack(self, frame, tb): stack = [] - if t and t.tb_frame is f: - t = t.tb_next - while f is not None: - stack.append((f, f.f_lineno)) - if f is self.botframe: + if tb and tb.tb_frame is frame: + tb = tb.tb_next + while frame is not None: + stack.append((frame, frame.f_lineno)) + if frame is self.botframe: break - f = f.f_back + frame = frame.f_back stack.reverse() i = max(0, len(stack) - 1) - while t is not None: - stack.append((t.tb_frame, t.tb_lineno)) - t = t.tb_next - if f is None: + while tb is not None: + stack.append((tb.tb_frame, tb.tb_lineno)) + tb = tb.tb_next + if frame is None: i = max(0, len(stack) - 1) return stack, i @@ -567,41 +599,40 @@ class Dumper: # a debugger to debug a statement or an expression. # Both can be given as a string, or a code object. - def run(self, cmd, globals=None, locals=None): - if globals is None: + def run(self, cmd, pyGlobals=None, pyLocals=None): + if pyGlobals is None: import __main__ - globals = __main__.__dict__ - if locals is None: - locals = globals + pyGlobals = __main__.__dict__ + if pyLocals is None: + pyLocals = pyGlobals self.reset() if isinstance(cmd, str): cmd = compile(cmd, '<string>', 'exec') sys.settrace(self.trace_dispatch) try: - exec(cmd, globals, locals) + exec(cmd, pyGlobals, pyLocals) except QuitException: pass finally: self.quitting = True sys.settrace(None) - def runeval(self, expr, globals=None, locals=None): - if globals is None: + def runeval(self, expr, pyGlobals=None, pyLocals=None): + if pyGlobals is None: import __main__ - globals = __main__.__dict__ - if locals is None: - locals = globals + pyGlobals = __main__.__dict__ + if pyLocals is None: + pyLocals = pyGlobals self.reset() sys.settrace(self.trace_dispatch) try: - return eval(expr, globals, locals) + return eval(expr, pyGlobals, pyLocals) except QuitException: pass finally: self.quitting = True sys.settrace(None) - # This method is more useful to debug a single function call. def runcall(self, func, *args, **kwds): self.reset() @@ -616,7 +647,6 @@ class Dumper: sys.settrace(None) return res - def cmdloop(self): """Repeatedly accept input, parse an initial prefix off the received input, and dispatch to action methods, passing them @@ -640,7 +670,7 @@ class Dumper: self.stdout.write('') self.stdout.flush() line = self.stdin.readline() - if not len(line): + if not line: line = 'EOF' else: line = line.rstrip('\r\n') @@ -664,8 +694,9 @@ class Dumper: line = 'shell ' + line[1:] else: return None, None, line - i, n = 0, len(line) - while i < n and line[i] in self.identchars: i = i+1 + i, length = 0, len(line) + while i < length and line[i] in self.identchars: + i = i+1 cmd, arg = line[:i], line[i:].strip() return cmd, arg, line @@ -683,7 +714,7 @@ class Dumper: if cmd is None: return self.default(line) self.lastcmd = line - if line == 'EOF' : + if line == 'EOF': self.lastcmd = '' if cmd == '': return self.default(line) @@ -691,11 +722,9 @@ class Dumper: func = getattr(self, 'do_' + cmd, None) if func: return func(arg) - else: - return self.default(line) + return self.default(line) def runit(self): - print('DIR: %s' % dir()) if sys.argv[0] == '-c': sys.argv = sys.argv[2:] @@ -714,12 +743,12 @@ class Dumper: # So we clear up the __main__ and set several special variables # (this gets rid of pdb's globals and cleans old variables on restarts). - #import __main__ - #__main__.__dict__.clear() - #__main__.__dict__.update({'__name__' : '__main__', - # '__file__' : mainpyfile, - # '__builtins__': __builtins__, - # }) + # import __main__ + # __main__.__dict__.clear() + # __main__.__dict__.update({'__name__' : '__main__', + # '__file__' : mainpyfile, + # '__builtins__': __builtins__, + # }) # When bdb sets tracing, a number of call and line events happens # BEFORE debugger even reaches user's code (and the exact sequence of @@ -760,14 +789,13 @@ class Dumper: signal.signal(signal.SIGINT, self._previous_sigint_handler) def forget(self): - self.lineno = None self.stack = [] self.curindex = 0 self.curframe = None - def setup(self, f, tb): + def setup(self, frame, tb): self.forget() - self.stack, self.curindex = self.get_stack(f, tb) + self.stack, self.curindex = self.get_stack(frame, tb) self.curframe = self.stack[self.curindex][0] # The f_locals dictionary is updated from the actual frame # locals whenever the .f_locals accessor is called, so we @@ -787,7 +815,7 @@ class Dumper: """This function is called when we stop or break at this line.""" if self._wait_for_mainpyfile: if (self.mainpyfile != self.canonic(frame.f_code.co_filename) - or frame.f_lineno <= 0): + or frame.f_lineno <= 0): return self._wait_for_mainpyfile = False if self.bp_commands(frame): @@ -809,8 +837,8 @@ class Dumper: self.onecmd(line) self.lastcmd = lastcmd_back self.forget() - return - return 1 + return False + return True def user_return(self, frame, return_value): """This function is called when a return trap is set here.""" @@ -834,13 +862,13 @@ class Dumper: # actually occurred in this case. The debugger uses this debug event to # stop when the debuggee is returning from such generators. prefix = 'Internal ' if (not exc_traceback - and exc_type is StopIteration) else '' + and exc_type is StopIteration) else '' self.message('%s%s' % (prefix, - traceback.format_exception_only(exc_type, exc_value)[-1].strip())) + traceback.format_exception_only(exc_type, exc_value)[-1].strip())) self.interaction(frame, exc_traceback) - def interaction(self, frame, traceback): - if self.setup(frame, traceback): + def interaction(self, frame, tb): + if self.setup(frame, tb): # no interaction desired at this time (happens if .pdbrc contains # a command like 'continue') self.forget() @@ -871,9 +899,10 @@ class Dumper: self.message(repr(obj)) def default(self, line): - if line[:1] == '!': line = line[1:] - locals = self.curframe_locals - globals = self.curframe.f_globals + if line[:1] == '!': + line = line[1:] + pyLocals = self.curframe_locals + pyGlobals = self.curframe.f_globals try: code = compile(line + '\n', '<stdin>', 'single') save_stdout = sys.stdout @@ -883,7 +912,7 @@ class Dumper: sys.stdin = self.stdin sys.stdout = self.stdout sys.displayhook = self.displayhook - exec(code, globals, locals) + exec(code, pyGlobals, pyLocals) finally: sys.stdout = save_stdout sys.stdin = save_stdin @@ -892,15 +921,16 @@ class Dumper: exc_info = sys.exc_info()[:2] self.error(traceback.format_exception_only(*exc_info)[-1].strip()) - def message(self, msg): + @staticmethod + def message(msg): print(msg) - pass - def error(self, msg): - #print('***'+ msg) + @staticmethod + def error(msg): + # print('***'+ msg) pass - def do_break(self, arg, temporary = 0): + def do_break(self, arg, temporary=0): """b(reak) [ ([filename:]lineno | function) [, condition] ] Without argument, list all breaks. @@ -918,7 +948,7 @@ class Dumper: if not arg: if self.breaks: # There's at least one self.message('Num Type Disp Enb Where') - for bp in Breakpoint.bpbynumber: + for bp in QtcInternalBreakpoint.bpbynumber: if bp: self.message(bp.bpformat()) return @@ -964,8 +994,8 @@ class Dumper: if hasattr(func, '__func__'): func = func.__func__ code = func.__code__ - #use co_name to identify the bkpt (function names - #could be aliased, but co_name is invariant) + # use co_name to identify the bkpt (function names + # could be aliased, but co_name is invariant) funcname = code.co_name lineno = code.co_firstlineno filename = code.co_filename @@ -976,7 +1006,7 @@ class Dumper: self.error('The specified object %r is not a function ' 'or was not found along sys.path.' % arg) return - funcname = ok # ok contains a function name + funcname = ok # ok contains a function name lineno = int(ln) if not filename: filename = self.defaultFile() @@ -1013,18 +1043,19 @@ class Dumper: idstring = identifier.split("'") if len(idstring) == 1: # not in single quotes - id = idstring[0].strip() + tmp_id = idstring[0].strip() elif len(idstring) == 3: # quoted - id = idstring[1].strip() + tmp_id = idstring[1].strip() else: return failed - if id == '': return failed - parts = id.split('.') + if tmp_id == '': + return failed + parts = tmp_id.split('.') # Protection for derived debuggers if parts[0] == 'self': del parts[0] - if len(parts) == 0: + if not parts: return failed # Best first guess at file to look at fname = self.defaultFile() @@ -1056,7 +1087,7 @@ class Dumper: line = line.strip() # Don't allow setting breakpoint at a blank line if (not line or (line[0] == '#') or - (line[:3] == '"""') or line[:3] == "'''"): + (line[:3] == '"""') or line[:3] == "'''"): self.error('Blank or comment') return 0 return lineno @@ -1166,7 +1197,7 @@ class Dumper: reply = 'no' reply = reply.strip().lower() if reply in ('y', 'yes'): - bplist = [bp for bp in Breakpoint.bpbynumber if bp] + bplist = [bp for bp in QtcInternalBreakpoint.bpbynumber if bp] self.clear_all_breaks() for bp in bplist: self.message('Deleted %s' % bp) @@ -1212,11 +1243,11 @@ class Dumper: lineno = int(arg) except ValueError: self.error('Error in argument: %r' % arg) - return + return 0 if lineno <= self.curframe.f_lineno: self.error('"until" line number is smaller than current ' 'line number') - return + return 0 else: lineno = None lineno = self.curframe.f_lineno + 1 @@ -1290,11 +1321,11 @@ class Dumper: executed in the current environment). """ sys.settrace(None) - globals = self.curframe.f_globals - locals = self.curframe_locals - p = Dumper(self.stdin, self.stdout) + pyGlobals = self.curframe.f_globals + pyLocals = self.curframe_locals + p = QtcInternalDumper(self.stdin, self.stdout) self.message('ENTERING RECURSIVE DEBUGGER') - sys.call_tracing(p.run, (arg, globals, locals)) + sys.call_tracing(p.run, (arg, pyGlobals, pyLocals)) self.message('LEAVING RECURSIVE DEBUGGER') sys.settrace(self.trace_dispatch) self.lastcmd = p.lastcmd @@ -1321,14 +1352,16 @@ class Dumper: Print the argument list of the current function. """ co = self.curframe.f_code - dict = self.curframe_locals + loc = self.curframe_locals n = co.co_argcount - if co.co_flags & 4: n = n+1 - if co.co_flags & 8: n = n+1 + if co.co_flags & 4: + n = n + 1 + if co.co_flags & 8: + n = n + 1 for i in range(n): name = co.co_varnames[i] - if name in dict: - self.message('%s = %r' % (name, dict[name])) + if name in loc: + self.message('%s = %r' % (name, loc[name])) else: self.message('%s = *** undefined ***' % (name,)) @@ -1353,8 +1386,7 @@ class Dumper: try: if frame is None: return eval(arg, self.curframe.f_globals, self.curframe_locals) - else: - return eval(arg, frame.f_globals, frame.f_locals) + return eval(arg, frame.f_globals, frame.f_locals) except: exc_info = sys.exc_info()[:2] err = traceback.format_exception_only(*exc_info)[-1].strip() @@ -1412,9 +1444,9 @@ class Dumper: if os.path.isabs(filename) and os.path.exists(filename): return filename f = os.path.join(sys.path[0], filename) - if os.path.exists(f) and self.canonic(f) == self.mainpyfile: + if os.path.exists(f) and self.canonic(f) == self.mainpyfile: return f - root, ext = os.path.splitext(filename) + ext = os.path.splitext(filename)[1] if ext == '': filename = filename + '.py' if os.path.isabs(filename): @@ -1440,14 +1472,14 @@ class Dumper: if frameNr == -1: frameNr = 0 - frame_lineno = self.stack[-1-frameNr] - frame, lineno = frame_lineno - filename = self.canonic(frame.f_code.co_filename) + frame_lineno = self.stack[-1 - frameNr] + frame = frame_lineno[0] self.output += 'data={' for var in frame.f_locals.keys(): if var in ('__file__', '__name__', '__package__', '__spec__', - '__doc__', '__loader__', '__cached__', '__the_dumper__'): + '__doc__', '__loader__', '__cached__', '__the_dumper__', + '__annotations__', 'QtcInternalBreakpoint', 'QtcInternalDumper'): continue value = frame.f_locals[var] # this applies only for anonymous arguments @@ -1471,7 +1503,7 @@ class Dumper: except: self.putValue('<unavailable>') self.put('}') - #self.dumpValue(eval(value), escapedExp, iname) + # self.dumpValue(eval(value), escapedExp, iname) self.output += '}' self.output += '{frame="%s"}' % frameNr @@ -1483,7 +1515,7 @@ class Dumper: self.output = '' def put(self, value): - #sys.stdout.write(value) + # sys.stdout.write(value) self.output += value def putField(self, name, value): @@ -1492,53 +1524,46 @@ class Dumper: def putItemCount(self, count): self.put('value="<%s items>",numchild="%s",' % (count, count)) - def cleanType(self, type): - t = str(type) + @staticmethod + def cleanType(typename): + t = str(typename) if t.startswith("<type '") and t.endswith("'>"): t = t[7:-2] if t.startswith("<class '") and t.endswith("'>"): t = t[8:-2] return t - def putType(self, type, priority = 0): - self.putField('type', self.cleanType(type)) + def putType(self, typeName, priority=0): + self.putField('type', QtcInternalDumper.cleanType(typeName)) def putNumChild(self, numchild): self.put('numchild="%s",' % numchild) - def putValue(self, value, encoding = None, priority = 0): + def putValue(self, value, encoding=None, priority=0): self.putField('value', value) def putName(self, name): self.put('name="%s",' % name) def isExpanded(self, iname): - #self.warn('IS EXPANDED: %s in %s' % (iname, self.expandedINames)) + # self.warn('IS EXPANDED: %s in %s' % (iname, self.expandedINames)) if iname.startswith('None'): raise "Illegal iname '%s'" % iname - #self.warn(' --> %s' % (iname in self.expandedINames)) + # self.warn(' --> %s' % (iname in self.expandedINames)) return iname in self.expandedINames def isExpandedIName(self, iname): return iname in self.expandedINames def itemFormat(self, item): - format = self.formats.get(str(cleanAddress(item.value.address))) - if format is None: - format = self.typeformats.get(str(item.value.type)) - return format - - # Hex encoding operating on str or bytes, return str. - def hexencode(self, s): - if sys.version_info[0] == 2: - return s.encode('hex') - if isinstance(s, str): - s = s.encode('utf8') - return base64.b16encode(s).decode('utf8') + form = self.formats.get(str(QtcInternalDumper.cleanAddress(item.value.address))) + if form is None: + form = self.typeformats.get(str(item.value.type)) + return form def dumpValue(self, value, name, iname): t = type(value) - tt = self.cleanType(t) + tt = QtcInternalDumper.cleanType(t) if tt == 'module' or tt == 'function': return if str(value).startswith("<class '"): @@ -1556,10 +1581,10 @@ class Dumper: elif tt == 'list' or tt == 'tuple': self.putType(tt) self.putItemCount(len(value)) - #self.putValue(value) + # self.putValue(value) self.put('children=[') - for i in range(len(value)): - self.dumpValue(value[i], str(i), '%s.%d' % (iname, i)) + for i, val in enumerate(value): + self.dumpValue(val, str(i), '%s.%d' % (iname, i)) self.put(']') elif tt == 'str': v = value @@ -1647,12 +1672,11 @@ class Dumper: self.put('],') self.put('},') - def warn(self, msg): self.putField('warning', msg) def listModules(self, args): - self.put('modules=['); + self.put('modules=[') for name in sys.modules: self.put('{') self.putName(name) @@ -1665,19 +1689,19 @@ class Dumper: moduleName = args['module'] module = sys.modules.get(moduleName, None) self.put("symbols={module='%s',symbols='%s'}" - % (module, dir(module) if module else [])) + % (module, dir(module) if module else [])) self.flushOutput() def assignValue(self, args): exp = args['expression'] value = args['value'] - cmd = '%s=%s' % (exp, exp, value) + cmd = '%s=%s' % (exp, value) eval(cmd, {}) self.put('CMD: "%s"' % cmd) self.flushOutput() def stackListFrames(self, args): - #result = 'stack={current-thread="%s"' % thread.GetThreadID() + # result = 'stack={current-thread="%s"' % thread.GetThreadID() result = 'stack={current-thread="%s"' % 1 result += ',frames=[' @@ -1698,12 +1722,13 @@ class Dumper: pass result += ']' - #result += ',hasmore="%d"' % isLimited - #result += ',limit="%d"' % limit + # result += ',hasmore="%d"' % isLimited + # result += ',limit="%d"' % limit result += '}' self.report(result) - def report(self, stuff): + @staticmethod + def report(stuff): sys.stdout.write('@\n' + stuff + '@\n') sys.stdout.flush() @@ -1713,5 +1738,6 @@ def qdebug(cmd, args): method = getattr(__the_dumper__, cmd) method(args) -__the_dumper__=Dumper() + +__the_dumper__ = QtcInternalDumper() __the_dumper__.runit() diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index a584e24e84..65b0828cdb 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -1972,7 +1972,10 @@ def qdump__QWeakPointer(d, value): qdump_QWeakPointerHelper(d, value, True) def qdump__QPointer(d, value): - qdump_QWeakPointerHelper(d, value['wp'], True, value.type[0]) + # actually, we'd use value['wp'] instead of value, but since we + # only split() on the result and the (sub-)object address is the + # same it does not matter but saves some cycles. + qdump_QWeakPointerHelper(d, value, True, value.type[0]) def qdump_QWeakPointerHelper(d, value, isWeak, innerType = None): if isWeak: diff --git a/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp b/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp index 73e360122a..73c8138a43 100644 --- a/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp +++ b/share/qtcreator/qml/qmlpuppet/commands/valueschangedcommand.cpp @@ -62,7 +62,7 @@ quint32 ValuesChangedCommand::keyNumber() const void ValuesChangedCommand::removeSharedMemorys(const QVector<qint32> &keyNumberVector) { - foreach (qint32 keyNumber, keyNumberVector) { + for (qint32 keyNumber : keyNumberVector) { SharedMemory *sharedMemory = globalSharedMemoryContainer()->take(keyNumber); delete sharedMemory; } diff --git a/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp b/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp index 91b77e27a6..8348cbecb0 100644 --- a/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp +++ b/share/qtcreator/qml/qmlpuppet/container/imagecontainer.cpp @@ -79,7 +79,7 @@ void ImageContainer::setImage(const QImage &image) void ImageContainer::removeSharedMemorys(const QVector<qint32> &keyNumberVector) { - foreach (qint32 keyNumber, keyNumberVector) { + for (qint32 keyNumber : keyNumberVector) { SharedMemory *sharedMemory = globalSharedMemoryContainer()->take(keyNumber); delete sharedMemory; } diff --git a/share/qtcreator/qml/qmlpuppet/container/sharedmemory.h b/share/qtcreator/qml/qmlpuppet/container/sharedmemory.h index 3266fa25ed..2b6466bbdb 100644 --- a/share/qtcreator/qml/qmlpuppet/container/sharedmemory.h +++ b/share/qtcreator/qml/qmlpuppet/container/sharedmemory.h @@ -62,7 +62,7 @@ protected: #ifdef Q_OS_UNIX bool initKeyInternal(); void cleanHandleInternal(); - bool createInternal(QSharedMemory::AccessMode mode, int size); + bool createInternal(QSharedMemory::AccessMode mode, size_t size); bool attachInternal(QSharedMemory::AccessMode mode); bool detachInternal(); int handle(); @@ -74,7 +74,7 @@ private: QSharedMemory m_sharedMemory; #else void *m_memory; - int m_size; + size_t m_size; QString m_key; QByteArray m_nativeKey; QSharedMemory::SharedMemoryError m_error; diff --git a/share/qtcreator/qml/qmlpuppet/container/sharedmemory_unix.cpp b/share/qtcreator/qml/qmlpuppet/container/sharedmemory_unix.cpp index 9cd0e2a953..47857eaac7 100644 --- a/share/qtcreator/qml/qmlpuppet/container/sharedmemory_unix.cpp +++ b/share/qtcreator/qml/qmlpuppet/container/sharedmemory_unix.cpp @@ -45,10 +45,6 @@ #include <private/qcore_unix_p.h> -#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) -#define QStringLiteral(str) QString::fromLatin1(str) -#endif - namespace QmlDesigner { class SharedMemoryLocker @@ -74,7 +70,7 @@ public: m_sharedMemory->m_errorString = QStringLiteral("%1: unable to lock").arg(function); m_sharedMemory->m_error = QSharedMemory::LockError; - m_sharedMemory = 0; + m_sharedMemory = nullptr; return false; } @@ -98,7 +94,7 @@ static QByteArray makePlatformSafeKey(const QString &key) SharedMemory::SharedMemory() - : m_memory(0), + : m_memory(nullptr), m_size(0), m_error(QSharedMemory::NoError), m_systemSemaphore(QString()), @@ -109,7 +105,7 @@ SharedMemory::SharedMemory() } SharedMemory::SharedMemory(const QString &key) - : m_memory(0), + : m_memory(nullptr), m_size(0), m_error(QSharedMemory::NoError), m_systemSemaphore(QString()), @@ -176,12 +172,12 @@ bool SharedMemory::create(int size, QSharedMemory::AccessMode mode) return false; } - return createInternal(mode ,size); + return createInternal(mode, size_t(size)); } int SharedMemory::size() const { - return m_size; + return int(m_size); } bool SharedMemory::attach(QSharedMemory::AccessMode mode) @@ -202,7 +198,7 @@ bool SharedMemory::attach(QSharedMemory::AccessMode mode) bool SharedMemory::isAttached() const { - return (0 != m_memory); + return m_memory != nullptr; } bool SharedMemory::detach() @@ -348,7 +344,7 @@ void SharedMemory::cleanHandleInternal() m_fileHandle = -1; } -bool SharedMemory::createInternal(QSharedMemory::AccessMode mode, int size) +bool SharedMemory::createInternal(QSharedMemory::AccessMode mode, size_t size) { detachInternal(); @@ -390,10 +386,10 @@ bool SharedMemory::createInternal(QSharedMemory::AccessMode mode, int size) struct stat statBuffer; if (fstat(m_fileHandle, &statBuffer) == -1) return false; - int fileSize = statBuffer.st_size; + size_t fileSize = size_t(statBuffer.st_size); if (fileSize < size) { - int returnValue = ftruncate(m_fileHandle, size); + int returnValue = ftruncate(m_fileHandle, ssize_t(size)); if (returnValue == -1) { switch (errno) { case EFBIG: @@ -414,12 +410,12 @@ bool SharedMemory::createInternal(QSharedMemory::AccessMode mode, int size) } int protection = mode == QSharedMemory::ReadOnly ? PROT_READ : PROT_WRITE; - m_memory = mmap(0, size, protection, MAP_SHARED, m_fileHandle, 0); + m_memory = mmap(nullptr, size, protection, MAP_SHARED, m_fileHandle, 0); if (m_memory == MAP_FAILED) { close(m_fileHandle); shm_unlink(m_nativeKey.constData()); - m_memory = 0; + m_memory = nullptr; m_fileHandle = -1; m_size = 0; @@ -460,13 +456,13 @@ bool SharedMemory::attachInternal(QSharedMemory::AccessMode mode) struct stat statBuffer; if (fstat(m_fileHandle, &statBuffer) == -1) return false; - int size = statBuffer.st_size; + size_t size = size_t(statBuffer.st_size); int protection = mode == QSharedMemory::ReadOnly ? PROT_READ : PROT_WRITE; - m_memory = mmap(0, size, protection, MAP_SHARED, m_fileHandle, 0); + m_memory = mmap(nullptr, size, protection, MAP_SHARED, m_fileHandle, 0); if (m_memory == MAP_FAILED) { - m_memory = 0; + m_memory = nullptr; return false; } @@ -480,7 +476,7 @@ bool SharedMemory::detachInternal() { if (m_memory) { munmap(m_memory, m_size); - m_memory = 0; + m_memory = nullptr; m_size = 0; } diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp index ca4792e7a0..5ac0e1057b 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp +++ b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.cpp @@ -72,9 +72,9 @@ namespace QmlDesigner { NodeInstanceClientProxy::NodeInstanceClientProxy(QObject *parent) : QObject(parent), - m_inputIoDevice(0), - m_outputIoDevice(0), - m_nodeInstanceServer(0), + m_inputIoDevice(nullptr), + m_outputIoDevice(nullptr), + m_nodeInstanceServer(nullptr), m_writeCommandCounter(0), m_synchronizeId(-1) { @@ -303,9 +303,8 @@ void NodeInstanceClientProxy::readDataStream() break; } - foreach (const QVariant &command, commandList) { + for (const QVariant &command : qAsConst(commandList)) dispatchCommand(command); - } } void NodeInstanceClientProxy::sendPuppetAliveCommand() diff --git a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h index a14bbb3b45..2c53a77c90 100644 --- a/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h +++ b/share/qtcreator/qml/qmlpuppet/instances/nodeinstanceclientproxy.h @@ -63,7 +63,7 @@ class NodeInstanceClientProxy : public QObject, public NodeInstanceClientInterfa Q_OBJECT public: - NodeInstanceClientProxy(QObject *parent = 0); + NodeInstanceClientProxy(QObject *parent = nullptr); void informationChanged(const InformationChangedCommand &command) override; void valuesChanged(const ValuesChangedCommand &command) override; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/componentnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/componentnodeinstance.cpp index f546548b41..ad81fbdf6e 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/componentnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/componentnodeinstance.cpp @@ -72,7 +72,8 @@ void ComponentNodeInstance::setNodeSource(const QString &source) setId(id()); if (component()->isError()) { - foreach (const QQmlError &error, component()->errors()) + const QList<QQmlError> errors = component()->errors(); + for (const QQmlError &error : errors) qWarning() << error; } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummycontextobject.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummycontextobject.h index a5257a2086..6afb5ad0ff 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummycontextobject.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/dummycontextobject.h @@ -38,7 +38,7 @@ class DummyContextObject : public QObject Q_PROPERTY(bool runningInDesigner READ runningInDesigner FINAL) public: - explicit DummyContextObject(QObject *parent = 0); + explicit DummyContextObject(QObject *parent = nullptr); QObject *parentDummy() const; void setParentDummy(QObject *parentDummy); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp index ad6867e930..5006281803 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp @@ -187,7 +187,7 @@ QList<ServerNodeInstance> NodeInstanceServer::createInstances(const QVector<Inst { Q_ASSERT(declarativeView() || quickView()); QList<ServerNodeInstance> instanceList; - foreach (const InstanceContainer &instanceContainer, containerVector) { + for (const InstanceContainer &instanceContainer : containerVector) { ServerNodeInstance instance; if (instanceContainer.nodeSourceType() == InstanceContainer::ComponentSource) { instance = ServerNodeInstance::create(this, instanceContainer, ServerNodeInstance::WrapAsComponent); @@ -585,13 +585,8 @@ QList<ServerNodeInstance> NodeInstanceServer::setupInstances(const CreateSceneCo setInstanceAuxiliaryData(container); } - - QListIterator<ServerNodeInstance> instanceListIterator(instanceList); - instanceListIterator.toBack(); - while (instanceListIterator.hasPrevious()) { - ServerNodeInstance instance = instanceListIterator.previous(); - instance.doComponentComplete(); - } + for (int i = instanceList.size(); --i >= 0; ) + instanceList[i].doComponentComplete(); return instanceList; } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp index 5f88683ffa..ec453956df 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp @@ -137,7 +137,7 @@ void ObjectNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNod void ObjectNodeInstance::setId(const QString &id) { if (!m_id.isEmpty() && context()) { - context()->engine()->rootContext()->setContextProperty(m_id, 0); + context()->engine()->rootContext()->setContextProperty(m_id, nullptr); } if (!id.isEmpty() && context()) { @@ -324,7 +324,7 @@ void ObjectNodeInstance::removeFromOldProperty(QObject *object, QObject *oldPare } if (object && object->parent()) - object->setParent(0); + object->setParent(nullptr); } void ObjectNodeInstance::addToNewProperty(QObject *object, QObject *newParent, const PropertyName &newParentProperty) @@ -649,14 +649,14 @@ QObject *ObjectNodeInstance::createPrimitive(const QString &typeName, int majorN QObject *ObjectNodeInstance::createPrimitiveFromSource(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context) { if (typeName.isEmpty()) - return 0; + return nullptr; QStringList parts = typeName.split("/"); const QString unqualifiedTypeName = parts.last(); parts.removeLast(); if (parts.isEmpty()) - return 0; + return nullptr; QString importString = parts.join(".") + " " + QString::number(majorNumber) + "." + QString::number(minorNumber); if (importString == "QtQuick 1.0") /* Workaround for implicit QQml import */ @@ -772,12 +772,12 @@ QObject *ObjectNodeInstance::object() const { if (!m_object.isNull() && !QmlPrivateGate::objectWasDeleted(m_object.data())) return m_object.data(); - return 0; + return nullptr; } QQuickItem *ObjectNodeInstance::contentItem() const { - return 0; + return nullptr; } bool ObjectNodeInstance::hasContent() const @@ -819,7 +819,7 @@ QQmlContext *ObjectNodeInstance::context() const return nodeInstanceServer()->context(); qWarning() << "Error: No NodeInstanceServer"; - return 0; + return nullptr; } QQmlEngine *ObjectNodeInstance::engine() const @@ -867,7 +867,7 @@ QImage ObjectNodeInstance::renderPreviewImage(const QSize & /*previewImageSize*/ QObject *ObjectNodeInstance::parent() const { if (!object()) - return 0; + return nullptr; return object()->parent(); } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.h index b8efccc7ec..0b6b696e1a 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.h @@ -33,7 +33,7 @@ class Qt5NodeInstanceClientProxy : public NodeInstanceClientProxy { Q_OBJECT public: - explicit Qt5NodeInstanceClientProxy(QObject *parent = 0); + explicit Qt5NodeInstanceClientProxy(QObject *parent = nullptr); }; } // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp index 2a9118625c..d8d45c4803 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp @@ -77,7 +77,7 @@ void Qt5NodeInstanceServer::initializeView() QQmlView *Qt5NodeInstanceServer::declarativeView() const { - return 0; + return nullptr; } QQmlEngine *Qt5NodeInstanceServer::engine() const @@ -85,7 +85,7 @@ QQmlEngine *Qt5NodeInstanceServer::engine() const if (quickView()) return quickView()->engine(); - return 0; + return nullptr; } void Qt5NodeInstanceServer::resizeCanvasSizeToRootItemSize() diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp index 761ad9cdfe..d061cdfc5d 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp @@ -95,7 +95,7 @@ QTransform QuickItemNodeInstance::transform() const QObject *QuickItemNodeInstance::parent() const { if (!quickItem() || !quickItem()->parentItem()) - return 0; + return nullptr; return quickItem()->parentItem(); } @@ -799,8 +799,8 @@ bool QuickItemNodeInstance::isAnchoredBySibling() const QQuickItem *QuickItemNodeInstance::quickItem() const { - if (object() == 0) - return 0; + if (object() == nullptr) + return nullptr; return static_cast<QQuickItem*>(object()); } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp index 11234b9521..87aea97d8d 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp @@ -160,7 +160,7 @@ Internal::ObjectNodeInstance::Pointer ServerNodeInstance::createInstance(QObject { Internal::ObjectNodeInstance::Pointer instance; - if (objectToBeWrapped == 0) + if (objectToBeWrapped == nullptr) instance = Internal::DummyNodeInstance::create(); else if (isSubclassOf(objectToBeWrapped, "Q3DSPresentationItem")) instance = Internal::Qt3DPresentationNodeInstance::create(objectToBeWrapped); @@ -198,28 +198,28 @@ ServerNodeInstance ServerNodeInstance::create(NodeInstanceServer *nodeInstanceSe Q_ASSERT(instanceContainer.instanceId() != -1); Q_ASSERT(nodeInstanceServer); - QObject *object = 0; + QObject *object = nullptr; if (componentWrap == WrapAsComponent) { object = Internal::ObjectNodeInstance::createComponentWrap(instanceContainer.nodeSource(), nodeInstanceServer->importCode(), nodeInstanceServer->context()); } else if (!instanceContainer.nodeSource().isEmpty()) { object = Internal::ObjectNodeInstance::createCustomParserObject(instanceContainer.nodeSource(), nodeInstanceServer->importCode(), nodeInstanceServer->context()); - if (object == 0) + if (object == nullptr) nodeInstanceServer->sendDebugOutput(DebugOutputCommand::ErrorType, QLatin1String("Custom parser object could not be created."), instanceContainer.instanceId()); } else if (!instanceContainer.componentPath().isEmpty()) { object = Internal::ObjectNodeInstance::createComponent(instanceContainer.componentPath(), nodeInstanceServer->context()); - if (object == 0) + if (object == nullptr) nodeInstanceServer->sendDebugOutput(DebugOutputCommand::ErrorType, QString("Component with path %1 could not be created.").arg(instanceContainer.componentPath()), instanceContainer.instanceId()); } else { object = Internal::ObjectNodeInstance::createPrimitive(QString::fromUtf8(instanceContainer.type()), instanceContainer.majorNumber(), instanceContainer.minorNumber(), nodeInstanceServer->context()); - if (object == 0) + if (object == nullptr) nodeInstanceServer->sendDebugOutput(DebugOutputCommand::ErrorType, QLatin1String("Item could not be created."), instanceContainer.instanceId()); } - if (object == 0) { + if (object == nullptr) { if (instanceContainer.metaType() == InstanceContainer::ItemMetaType) { //If we cannot instanciate the object but we know it has to be an Ttem, we create an Item instead. object = Internal::ObjectNodeInstance::createPrimitive("QtQuick/Item", 2, 0, nodeInstanceServer->context()); - if (object == 0) + if (object == nullptr) object = new QQuickItem; } else { object = Internal::ObjectNodeInstance::createPrimitive("QtQml/QtObject", 2, 0, nodeInstanceServer->context()); @@ -549,7 +549,7 @@ void ServerNodeInstance::paintUpdate() QObject *ServerNodeInstance::internalObject() const { if (m_nodeInstance.isNull()) - return 0; + return nullptr; return m_nodeInstance->object(); } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h index c0c3f87608..b37c153f65 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h @@ -123,7 +123,7 @@ public: PropertyNameList propertyNames() const; - bool hasBindingForProperty(const PropertyName &name, bool *hasChanged = 0) const; + bool hasBindingForProperty(const PropertyName &name, bool *hasChanged = nullptr) const; bool isValid() const; void makeInvalid(); diff --git a/share/qtcreator/qml/qmlpuppet/qmlprivategate/metaobject.cpp b/share/qtcreator/qml/qmlpuppet/qmlprivategate/metaobject.cpp index 08caa70368..86049c9654 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlprivategate/metaobject.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlprivategate/metaobject.cpp @@ -183,7 +183,7 @@ void MetaObject::createNewDynamicProperty(const QString &name) copyTypeMetaObject(); setValue(id, QVariant()); Q_ASSERT(id >= 0); - Q_UNUSED(id); + Q_UNUSED(id) //Updating cache QQmlPropertyCache *oldParent = m_cache->parent(); diff --git a/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate.h b/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate.h index 4e90bad1fc..b0b68907ed 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate.h +++ b/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate.h @@ -70,10 +70,10 @@ public: bool isPropertyBlackListed(const QmlDesigner::PropertyName &propertyName); PropertyNameList propertyNameListForWritableProperties(QObject *object, const PropertyName &baseName = PropertyName(), - QObjectList *inspectedObjects = 0); + QObjectList *inspectedObjects = nullptr); PropertyNameList allPropertyNames(QObject *object, const PropertyName &baseName = PropertyName(), - QObjectList *inspectedObjects = 0); + QObjectList *inspectedObjects = nullptr); bool hasFullImplementedListInterface(const QQmlListReference &list); void registerCustomData(QObject *object); diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml index e377dcdf33..80882ac213 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml @@ -27,6 +27,7 @@ import QtQuick 2.1 import StudioControls 1.0 as StudioControls import StudioTheme 1.0 as StudioTheme import QtQuickDesignerTheme 1.0 +import HelperWidgets 2.0 Item { id: extendedFunctionButton @@ -143,62 +144,27 @@ Item { function show() { expressionDialogLoader.visible = true } + sourceComponent: Item { + id: bindingEditorParent + + Component.onCompleted: { + var x = extendedFunctionButton.mapToGlobal(0,0).x - 200 + var y = extendedFunctionButton.mapToGlobal(0,0).y - 40 + bindingEditor.showWidget(x, y) + bindingEditor.text = backendValue.expression + } - sourceComponent: Component { - Item { - id: expressionDialog - anchors.fill: parent - - Component.onCompleted: { - textField.text = backendValue.expression - textField.forceActiveFocus() - } - - Rectangle { - anchors.fill: parent - color: Theme.qmlDesignerBackgroundColorDarker() - opacity: 0.6 - } + BindingEditor { + id: bindingEditor - MouseArea { - anchors.fill: parent - onDoubleClicked: expressionDialog.visible = false + onRejected: { + hideWidget() + expressionDialogLoader.visible = false } - - Rectangle { - x: 4 - Component.onCompleted: { - var pos = itemPane.mapFromItem( - extendedFunctionButton.parent, 0, 0) - y = pos.y + 2 - } - - width: parent.width - 8 - height: 260 - - radius: 2 - color: Theme.qmlDesignerBackgroundColorDarkAlternate() - border.color: Theme.qmlDesignerBorderColor() - - Label { - x: 8 - y: 6 - font.bold: true - text: qsTr("Binding Editor") - } - ExpressionTextField { - id: textField - onRejected: expressionDialogLoader.visible = false - onAccepted: { - backendValue.expression = textField.text.trim() - expressionDialogLoader.visible = false - } - anchors.fill: parent - anchors.leftMargin: 8 - anchors.rightMargin: 8 - anchors.topMargin: 24 - anchors.bottomMargin: 32 - } + onAccepted: { + backendValue.expression = bindingEditor.text.trim() + hideWidget() + expressionDialogLoader.visible = false } } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPresetTabContent.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPresetTabContent.qml index ded679b624..c955cd8bc6 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPresetTabContent.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/GradientPresetTabContent.qml @@ -31,6 +31,7 @@ import QtQuick.Dialogs 1.3 import HelperWidgets 2.0 import QtQuickDesignerTheme 1.0 +import QtQuick.Controls.Private 1.0 as PrivateControls Rectangle { @@ -45,9 +46,9 @@ Rectangle { signal presetNameChanged(int id, string name) signal deleteButtonClicked(int id) - property int delegateWidth: 153; - property int delegateHeight: 173; - property int gridCellWidth: 160; + property real delegateWidth: 154; + property real delegateHeight: 178; + property real gridCellWidth: 160; ScrollView { @@ -66,7 +67,7 @@ Rectangle { property int gridColumns: width / tabBackground.gridCellWidth; cellWidth: width / gridColumns - cellHeight: 180 + cellHeight: 185 Component { id: gradientDelegate @@ -74,12 +75,13 @@ Rectangle { Rectangle { id: backgroundCard color: "#404040" - clip: false + clip: true property real flexibleWidth: (gradientTable.width - gradientTable.cellWidth * gradientTable.gridColumns) / gradientTable.gridColumns property bool isSelected: false - width: gradientTable.cellWidth + flexibleWidth - 8; height: tabBackground.delegateHeight + width: gradientTable.cellWidth + flexibleWidth - 8 + height: tabBackground.delegateHeight radius: 16 MouseArea { @@ -125,8 +127,6 @@ Rectangle { PropertyChanges { target: backgroundCard color: "#606060" - z: 5 - clip: true border.width: 1 border.color: "#029de0" } @@ -136,8 +136,6 @@ Rectangle { PropertyChanges { target: backgroundCard color:"#029de0" - z: 4 - clip: true border.width: 1 border.color: "#606060" } @@ -148,21 +146,22 @@ Rectangle { { target: backgroundCard color: "#404040" - scale: 1.0 border.width: 0 } } ] //states ColumnLayout { + spacing: 2 anchors.fill: parent Rectangle { width: 150; height: 150 id: gradientRect radius: 16 - Layout.alignment: Qt.AlignHCenter | Qt.AlignTop + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter //was top Layout.topMargin: 2 + gradient: Gradient { id: showGr } @@ -184,54 +183,178 @@ Rectangle { Rectangle { id: removeItemRect anchors.right: parent.right - anchors.rightMargin: 2 + anchors.rightMargin: 5 anchors.top: parent.top - anchors.topMargin: 2 + anchors.topMargin: 5 height: 16 width: 16 visible: editableName && rectMouseArea.containsMouse color: "#804682b4" - MouseArea { anchors.fill: parent; onClicked: tabBackground.deleteButtonClicked(index); } Image { - id: remoreItemImg source: "image://icons/close" fillMode: Image.PreserveAspectFit anchors.fill: parent; Layout.alignment: Qt.AlignCenter - } - } + } //image remove + } //rectangle remove } //rectangle gradient - TextInput { + Item { id: presetNameBox - readOnly: !editableName - text: (presetName) - Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom - Layout.preferredWidth: backgroundCard.width - Layout.topMargin: -5 - padding: 5.0 - topPadding: -2.0 - horizontalAlignment: Text.AlignHCenter - wrapMode: Text.Wrap - color: "#ffffff" - activeFocusOnPress: true - - onEditingFinished: tabBackground.presetNameChanged(index, text); - - Keys.onPressed: { - if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { - event.accepted = true; - editingFinished(); - focus = false; + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + Layout.preferredWidth: backgroundCard.width - 2 + Layout.preferredHeight: backgroundCard.height - gradientRect.height - 4 + Layout.bottomMargin: 4 + + property bool readOnly : true; + + onReadOnlyChanged: { + if (!readOnly) { + nameInput.visible = true; + nameInput.forceActiveFocus(); + + //have to select text like this, otherwise there is an issue with long names + nameInput.cursorPosition = 0; + nameInput.cursorPosition = nameInput.length; + nameInput.selectAll(); + } + } //onReadOnlyChanged + + Rectangle { + id: nameBackgroundColor + enabled: tabBackground.editableName + color: "transparent" + radius: 16 + visible: true + anchors.fill: parent + } //rectangle + + MouseArea { + id: nameMouseArea + visible: tabBackground.editableName + hoverEnabled: true + anchors.fill: parent + + onClicked: presetNameBox.state = "Clicked"; + + onEntered: { + if (presetNameBox.state != "Clicked") + { + presetNameBox.state = "Hover"; + } + } + + onExited: { + if (presetNameBox.state != "Clicked") + { + presetNameBox.state = "Normal"; + } + PrivateControls.Tooltip.hideText() + } + + Timer { + interval: 1000 + running: nameMouseArea.containsMouse && presetNameBox.readOnly + onTriggered: PrivateControls.Tooltip.showText(nameMouseArea, Qt.point(nameMouseArea.mouseX, nameMouseArea.mouseY), presetName) + } + + onCanceled: Tooltip.hideText() + + } //mouseArea + + Text { + id: nameText + visible: presetNameBox.readOnly + text: presetName + anchors.fill: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + color: "#ffffff" + elide: Text.ElideMiddle + maximumLineCount: 1 + } //text + + + TextInput { + id: nameInput + visible: !presetNameBox.readOnly + text: presetName + anchors.fill: parent + anchors.leftMargin: 5 + anchors.rightMargin: 5 + horizontalAlignment: TextInput.AlignHCenter + verticalAlignment: TextInput.AlignVCenter + color: "#ffffff" + selectionColor: "#029de0" + activeFocusOnPress: true + wrapMode: TextInput.NoWrap + clip: true + + onEditingFinished: { + nameText.text = text + tabBackground.presetNameChanged(index, text); + presetNameBox.state = "Normal"; + } + + Keys.onPressed: { + if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { + event.accepted = true; + editingFinished(); + focus = false; + } //if + } //Keys.onPressed + } //textInput + + states: [ + State { + name: "Normal" + PropertyChanges { + target: nameBackgroundColor + color: "transparent" + border.width: 0 + } + PropertyChanges { + target: presetNameBox + readOnly: true + } + }, + State { + name: "Hover" + PropertyChanges { + target: nameBackgroundColor + color: "#606060" + border.width: 0 + } + PropertyChanges { + target: presetNameBox + readOnly: true + } + }, + State { + name: "Clicked" + PropertyChanges { + target: nameBackgroundColor + color: "#606060" + border.color: "#029de0" + border.width: 1 + } + PropertyChanges { + target: presetNameBox + readOnly: false + } + PropertyChanges { + target: nameInput + visible: true + } } - } //Keys.onPressed - } //textInput + ] //states + } //gradient name Item } //columnLayout } //rectangle background } //component delegate diff --git a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml index 26d4c21cc9..5f044b73f4 100644 --- a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml +++ b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml @@ -30,7 +30,6 @@ import HelperWidgets 2.0 import QtQuickDesignerTheme 1.0 Rectangle { - z: expressionTextField.visible ? 5 : 0 border.width: 1 property bool isBaseState property bool isCurrentState @@ -111,9 +110,10 @@ Rectangle { MenuItem { text: qsTr("Set when Condition") onTriggered: { - expressionTextField.text = delegateWhenConditionString - expressionTextField.visible = true - expressionTextField.forceActiveFocus() + var x = whenButton.mapToGlobal(0,0).x + 4 + var y = root.mapToGlobal(0,0).y - 32 + bindingEditor.showWidget(x, y) + bindingEditor.text = delegateWhenConditionString } } @@ -192,19 +192,27 @@ Rectangle { } } - ExpressionTextField { - id: expressionTextField + BindingEditor { + property string newWhenCondition - parent: root - visible: false - onAccepted: { - visible = false - statesEditorModel.setWhenCondition(internalNodeId, expressionTextField.text.trim()) + property Timer timer: Timer { + id: timer + running: false + interval: 50 + repeat: false + onTriggered: statesEditorModel.setWhenCondition(internalNodeId, bindingEditor.newWhenCondition) } - onRejected: visible = false + id: bindingEditor - anchors.fill: parent + onRejected: { + hideWidget() + } + onAccepted: { + bindingEditor.newWhenCondition = bindingEditor.text.trim() + timer.start() + hideWidget() + } } } diff --git a/share/qtcreator/scripts/openTerminal.py b/share/qtcreator/scripts/openTerminal.py index afcb94d632..e931c6bb26 100755 --- a/share/qtcreator/scripts/openTerminal.py +++ b/share/qtcreator/scripts/openTerminal.py @@ -105,7 +105,8 @@ def main(): login_script() + 'cd ' + quote_shell(os.getcwd()) + '\n' + ' '.join([quote_shell(arg) for arg in sys.argv[1:]]) + '\n' + - 'rm ' + quoted_shell_script + '\n' + 'rm ' + quoted_shell_script + '\n' + + 'exit\n' if len(sys.argv) > 1 else '' ) shell_script.write(commands) shell_script.flush() diff --git a/share/qtcreator/templates/wizards/autotest/files/googlecommon.js b/share/qtcreator/templates/wizards/autotest/files/googlecommon.js index 1079ed5fdf..7f754cc9e8 100644 --- a/share/qtcreator/templates/wizards/autotest/files/googlecommon.js +++ b/share/qtcreator/templates/wizards/autotest/files/googlecommon.js @@ -13,12 +13,13 @@ ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** **/ +var File = require("qbs.File") var FileInfo = require("qbs.FileInfo") function getGTestDir(qbs, str) { if (!str) { - if (qbs.hostOS.contains("linux")) - return "/usr/include/gtest"; + if (qbs.hostOS.contains("linux") && File.exists("/usr/src/gtest")) + return "/usr/src/gtest"; } else { return FileInfo.joinPaths(str, "googletest"); } @@ -27,8 +28,8 @@ function getGTestDir(qbs, str) { function getGMockDir(qbs, str) { if (!str) { - if (qbs.hostOS.contains("linux")) - return "/usr/include/gmock"; + if (qbs.hostOS.contains("linux") && File.exists("/usr/src/gmock")) + return "/usr/src/gmock"; } else { return FileInfo.joinPaths(str, "googlemock"); } diff --git a/share/qtcreator/templates/wizards/autotest/files/gtest_dependency.pri b/share/qtcreator/templates/wizards/autotest/files/gtest_dependency.pri index c01bab677c..c064ef6242 100644 --- a/share/qtcreator/templates/wizards/autotest/files/gtest_dependency.pri +++ b/share/qtcreator/templates/wizards/autotest/files/gtest_dependency.pri @@ -1,31 +1,43 @@ isEmpty(GOOGLETEST_DIR):GOOGLETEST_DIR=$$(GOOGLETEST_DIR) isEmpty(GOOGLETEST_DIR) { - warning("Using googletest src dir specified at Qt Creator wizard") - message("set GOOGLETEST_DIR as environment variable or qmake variable to get rid of this message") GOOGLETEST_DIR = %{GTestRepository} + !isEmpty(GOOGLETEST_DIR) { + warning("Using googletest src dir specified at Qt Creator wizard") + message("set GOOGLETEST_DIR as environment variable or qmake variable to get rid of this message") + } } !isEmpty(GOOGLETEST_DIR): { GTEST_SRCDIR = $$GOOGLETEST_DIR/googletest GMOCK_SRCDIR = $$GOOGLETEST_DIR/googlemock +} else: unix { + exists(/usr/src/gtest):GTEST_SRCDIR=/usr/src/gtest + exists(/usr/src/gmock):GMOCK_SRCDIR=/usr/src/gmock + !isEmpty(GTEST_SRCDIR): message("Using gtest from system") } requires(exists($$GTEST_SRCDIR):exists($$GMOCK_SRCDIR)) -!exists($$GOOGLETEST_DIR):message("No googletest src dir found - set GOOGLETEST_DIR to enable.") - @if "%{GTestCXX11}" == "true" DEFINES += \\ GTEST_LANG_CXX11 @endif -INCLUDEPATH *= \\ - $$GTEST_SRCDIR \\ - $$GTEST_SRCDIR/include \\ - $$GMOCK_SRCDIR \\ - $$GMOCK_SRCDIR/include +!isEmpty(GTEST_SRCDIR) { + INCLUDEPATH *= \\ + $$GTEST_SRCDIR \\ + $$GTEST_SRCDIR/include + + SOURCES += \\ + $$GTEST_SRCDIR/src/gtest-all.cc +} -SOURCES += \\ - $$GTEST_SRCDIR/src/gtest-all.cc \\ - $$GMOCK_SRCDIR/src/gmock-all.cc +!isEmpty(GMOCK_SRCDIR) { + INCLUDEPATH *= \\ + $$GMOCK_SRCDIR \\ + $$GMOCK_SRCDIR/include + + SOURCES += \\ + $$GMOCK_SRCDIR/src/gmock-all.cc +} diff --git a/share/qtcreator/templates/wizards/autotest/files/tst.qbs b/share/qtcreator/templates/wizards/autotest/files/tst.qbs index 92a0656d65..e66605f0a5 100644 --- a/share/qtcreator/templates/wizards/autotest/files/tst.qbs +++ b/share/qtcreator/templates/wizards/autotest/files/tst.qbs @@ -26,8 +26,12 @@ CppApplication { @if "%{TestFrameWork}" == "GTest" property string googletestDir: { if (typeof Environment.getEnv("GOOGLETEST_DIR") === 'undefined') { - console.warn("Using googletest src dir specified at Qt Creator wizard") - console.log("set GOOGLETEST_DIR as environment variable or Qbs property to get rid of this message") + if ("%{GTestRepository}" === "" && googleCommon.getGTestDir(qbs, undefined) !== "") { + console.warn("Using googletest from system") + } else { + console.warn("Using googletest src dir specified at Qt Creator wizard") + console.log("set GOOGLETEST_DIR as environment variable or Qbs property to get rid of this message") + } return "%{GTestRepository}" } else { return Environment.getEnv("GOOGLETEST_DIR") diff --git a/share/qtcreator/templates/wizards/autotest/files/tst.txt b/share/qtcreator/templates/wizards/autotest/files/tst.txt index bf5e75ff16..f1d57e97ab 100644 --- a/share/qtcreator/templates/wizards/autotest/files/tst.txt +++ b/share/qtcreator/templates/wizards/autotest/files/tst.txt @@ -62,22 +62,35 @@ find_package(Threads REQUIRED) if ($ENV{GOOGLETEST_DIR}) set(GOOGLETEST_DIR $ENV{GOOGLETEST_DIR}) else () - message(WARNING "Using googletest src dir specified at Qt Creator wizard") + if (NOT "%{GTestRepository}" STREQUAL "") + message(WARNING "Using googletest src dir specified at Qt Creator wizard") + endif () set(GOOGLETEST_DIR "%{GTestRepository}") endif () if (EXISTS ${GOOGLETEST_DIR}) set(GTestSrc ${GOOGLETEST_DIR}/googletest) set(GMockSrc ${GOOGLETEST_DIR}/googlemock) +elseif (UNIX AND EXISTS /usr/src/gtest) + set(GTestSrc /usr/src/gtest) + message(WARNING "Using gtest from system") + if (EXISTS /usr/src/gmock) + set(GMockSrc /usr/src/gmock) + endif () else () message( FATAL_ERROR "No googletest src dir found - set GOOGLETEST_DIR to enable!") endif () +set(GTestFiles ${GTestSrc}/src/gtest-all.cc) +set(GTestIncludes ${GTestSrc} ${GTestSrc}/include) +if (NOT ${GMockSrc} STREQUAL "") + list(APPEND GTestFiles ${GMockSrc}/src/gmock-all.cc) + list(APPEND GTestIncludes ${GMockSrc} ${GMockSrc}/include) +endif () -include_directories(${GTestSrc} ${GTestSrc}/include ${GMockSrc} ${GMockSrc}/include) +include_directories(${GTestIncludes}) add_executable(%{TestCaseName} %{MainCppName} %{TestCaseFileWithHeaderSuffix} - ${GTestSrc}/src/gtest-all.cc - ${GMockSrc}/src/gmock-all.cc) + ${GTestFiles}) add_test(%{TestCaseName} COMMAND %{TestCaseName}) target_link_libraries(%{TestCaseName} PRIVATE Threads::Threads) diff --git a/share/qtcreator/templates/wizards/autotest/wizard.json b/share/qtcreator/templates/wizards/autotest/wizard.json index 83a4be09a4..6744a14a8c 100644 --- a/share/qtcreator/templates/wizards/autotest/wizard.json +++ b/share/qtcreator/templates/wizards/autotest/wizard.json @@ -149,8 +149,9 @@ }, { "name": "GTestRepository", - "trDisplayName": "Googletest repository:", + "trDisplayName": "Googletest source directory (optional):", "visible": "%{JS: value('TestFrameWork') === 'GTest'}", + "mandatory": false, "type": "PathChooser", "data": { "kind": "existingDirectory" @@ -158,7 +159,7 @@ }, { "name": "BoostIncDir", - "trDisplayName": "Boost include dir (optional):", + "trDisplayName": "Boost include directory (optional):", "visible": "%{JS: value('TestFrameWork') == 'BoostTest'}", "mandatory": false, "type": "PathChooser", diff --git a/share/qtcreator/templates/wizards/classes/cpp/file.h b/share/qtcreator/templates/wizards/classes/cpp/file.h index 583c63dd30..aa2fa7faaf 100644 --- a/share/qtcreator/templates/wizards/classes/cpp/file.h +++ b/share/qtcreator/templates/wizards/classes/cpp/file.h @@ -28,7 +28,7 @@ class %{CN} : public %{Base} class %{CN} @endif { -@if %{isQObject} +@if '%{AddQObjectMacro}' Q_OBJECT @endif public: @@ -46,9 +46,12 @@ public: @endif @if %{isQObject} +@if %{QtKeywordsEnabled} signals: +@else +Q_SIGNALS: +@endif -public slots: @endif @if '%{IncludeQSharedData}' diff --git a/share/qtcreator/templates/wizards/classes/cpp/wizard.json b/share/qtcreator/templates/wizards/classes/cpp/wizard.json index ae466ba7ed..bb8a1f9fef 100644 --- a/share/qtcreator/templates/wizards/classes/cpp/wizard.json +++ b/share/qtcreator/templates/wizards/classes/cpp/wizard.json @@ -18,7 +18,8 @@ { "key": "Base", "value": "%{JS: value('BaseCB') === '' ? value('BaseEdit') : value('BaseCB')}" }, { "key": "isQObject", "value": "%{JS: [ 'QObject', 'QWidget', 'QMainWindow', 'QDeclarativeItem', 'QQuickItem'].indexOf(value('Base')) >= 0 }" }, { "key": "GUARD", "value": "%{JS: Cpp.classToHeaderGuard(value('Class'), Util.suffix(value('HdrFileName')))}" }, - { "key": "SharedDataInit", "value": "%{JS: (value('IncludeQSharedData')) ? 'data(new %{CN}Data)' : '' }" } + { "key": "SharedDataInit", "value": "%{JS: (value('IncludeQSharedData')) ? 'data(new %{CN}Data)' : '' }" }, + { "key": "Dependencies", "value": "%{JS: '' + (value('IncludeQObject') || value('IncludeQSharedData') || value('BaseCB') === 'QObject' ? ':Qt.core' : '') + (value('IncludeQWidget') || value('IncludeQMainWindow') || value('BaseCB') === 'QWidget' || value('BaseCB') === 'QMainWindow' ? ':Qt.widgets' : '') + (value('IncludeQQuickItem') || value('BaseCB') === 'QQuickItem' ? ':Qt.quick' : '')}"} ], "pages": @@ -130,6 +131,17 @@ } }, { + "name": "AddQObjectMacro", + "trDisplayName": "Add Q_OBJECT", + "type": "CheckBox", + "data": + { + "checkedValue": "AddQObjectMacro", + "uncheckedValue": "", + "checked": "%{JS: [ 'QObject', 'QWidget', 'QMainWindow', 'QDeclarativeItem', 'QQuickItem'].indexOf(value('Base')) >= 0 }" + } + }, + { "name": "Sp2", "type": "Spacer" }, diff --git a/share/qtcreator/templates/wizards/classes/python/wizard.json b/share/qtcreator/templates/wizards/classes/python/wizard.json index 233a8bac7a..552c3f15a0 100644 --- a/share/qtcreator/templates/wizards/classes/python/wizard.json +++ b/share/qtcreator/templates/wizards/classes/python/wizard.json @@ -7,7 +7,7 @@ "trDisplayName": "Python Class", "trDisplayCategory": "Python", "icon": "../../files/python/icon.png", - "enabled": "%{JS: value('Plugins').indexOf('PythonEditor') >= 0}", + "enabled": "%{JS: value('Plugins').indexOf('Python') >= 0}", "options": [ diff --git a/share/qtcreator/templates/wizards/files/python/wizard.json b/share/qtcreator/templates/wizards/files/python/wizard.json index 262de2d37b..f3bff037b5 100644 --- a/share/qtcreator/templates/wizards/files/python/wizard.json +++ b/share/qtcreator/templates/wizards/files/python/wizard.json @@ -7,7 +7,7 @@ "trDisplayName": "Python File", "trDisplayCategory": "Python", "icon": "icon.png", - "enabled": "%{JS: value('Plugins').indexOf('PythonEditor') >= 0}", + "enabled": "%{JS: value('Plugins').indexOf('Python') >= 0}", "pages" : [ diff --git a/share/qtcreator/templates/wizards/projects/consoleapp/CMakeLists.txt b/share/qtcreator/templates/wizards/projects/consoleapp/CMakeLists.txt index ce63061d75..d7eda0b02d 100644 --- a/share/qtcreator/templates/wizards/projects/consoleapp/CMakeLists.txt +++ b/share/qtcreator/templates/wizards/projects/consoleapp/CMakeLists.txt @@ -11,7 +11,22 @@ set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) +@if %{HasTranslation} +find_package(Qt5 COMPONENTS Core LinguistTools REQUIRED) + +set(TS_FILES %{TsFileName}) +@else find_package(Qt5Core) +@endif -add_executable(%{ProjectName} %{CppFileName}) +add_executable(%{ProjectName} + %{CppFileName} +@if %{HasTranslation} + ${TS_FILES} +@endif +) target_link_libraries(%{ProjectName} Qt5::Core) +@if %{HasTranslation} + +qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES}) +@endif diff --git a/share/qtcreator/templates/wizards/projects/consoleapp/file.pro b/share/qtcreator/templates/wizards/projects/consoleapp/file.pro index d38289ce09..a8ed27c2ad 100644 --- a/share/qtcreator/templates/wizards/projects/consoleapp/file.pro +++ b/share/qtcreator/templates/wizards/projects/consoleapp/file.pro @@ -16,6 +16,11 @@ DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \\ %{CppFileName} +@if %{HasTranslation} + +TRANSLATIONS += \\ + %{TsFileName} +@endif # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin diff --git a/share/qtcreator/templates/wizards/projects/consoleapp/file.qbs b/share/qtcreator/templates/wizards/projects/consoleapp/file.qbs index 3587027384..dfdd823780 100644 --- a/share/qtcreator/templates/wizards/projects/consoleapp/file.qbs +++ b/share/qtcreator/templates/wizards/projects/consoleapp/file.qbs @@ -17,7 +17,12 @@ QtApplication { ] consoleApplication: true - files: "%{CppFileName}" + files: [ + "%{CppFileName}", +@if %{HasTranslation} + "%{TsFileName}", +@endif + ] Group { // Properties for the produced executable fileTagsFilter: "application" diff --git a/share/qtcreator/templates/wizards/projects/consoleapp/wizard.json b/share/qtcreator/templates/wizards/projects/consoleapp/wizard.json index bee602c87d..b500c9edf4 100644 --- a/share/qtcreator/templates/wizards/projects/consoleapp/wizard.json +++ b/share/qtcreator/templates/wizards/projects/consoleapp/wizard.json @@ -16,6 +16,7 @@ { "key": "ProFile", "value": "%{JS: Util.fileName(value('ProjectDirectory') + '/' + value('ProjectName'), 'pro')}" }, { "key": "QbsFile", "value": "%{JS: Util.fileName(value('ProjectDirectory') + '/' + value('ProjectName'), 'qbs')}" }, { "key": "CMakeFile", "value": "%{ProjectDirectory}/CMakeLists.txt" }, + { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" }, { "key": "CppFileName", "value": "%{JS: 'main.' + Util.preferredSuffix('text/x-c++src')}" } ], @@ -64,6 +65,11 @@ ] }, { + "trDisplayName": "Translation File", + "trShortTitle": "Translation", + "typeId": "QtTranslation" + }, + { "trDisplayName": "Kit Selection", "trShortTitle": "Kits", "typeId": "Kits", @@ -105,6 +111,11 @@ "openInEditor": true }, { + "source": "../translation.ts", + "target": "%{TsFileName}", + "condition": "%{HasTranslation}" + }, + { "source": "../git.ignore", "target": ".gitignore", "condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}" diff --git a/share/qtcreator/templates/wizards/projects/cpplibrary/CMakeLists.txt b/share/qtcreator/templates/wizards/projects/cpplibrary/CMakeLists.txt index 243280b657..b69799a442 100644 --- a/share/qtcreator/templates/wizards/projects/cpplibrary/CMakeLists.txt +++ b/share/qtcreator/templates/wizards/projects/cpplibrary/CMakeLists.txt @@ -12,8 +12,14 @@ set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) @if '%{QtModule}' != 'none' +@if %{HasTranslation} +find_package(Qt5 COMPONENTS %{QtModuleUpperCase} LinguistTools REQUIRED) + +set(TS_FILES %{TsFileName}) +@else find_package(Qt5 COMPONENTS %{QtModuleUpperCase} REQUIRED) @endif +@endif add_library(%{ProjectName} %{JS: %{IsStatic} ? 'STATIC' : 'SHARED'} @if '%{Type}' === 'shared' @@ -24,6 +30,9 @@ add_library(%{ProjectName} %{JS: %{IsStatic} ? 'STATIC' : 'SHARED'} @if %{IsQtPlugin} %{PluginJsonFile} @endif +@if %{HasTranslation} + ${TS_FILES} +@endif ) @if '%{QtModule}' != 'none' @@ -33,3 +42,7 @@ target_link_libraries(%{ProjectName} PRIVATE Qt5::%{QtModuleUpperCase}) target_compile_definitions(%{ProjectName} PRIVATE %{LibraryDefine}) @endif +@if %{HasTranslation} + +qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES}) +@endif diff --git a/share/qtcreator/templates/wizards/projects/cpplibrary/project.pro b/share/qtcreator/templates/wizards/projects/cpplibrary/project.pro index 431667ada5..8eba894fe5 100644 --- a/share/qtcreator/templates/wizards/projects/cpplibrary/project.pro +++ b/share/qtcreator/templates/wizards/projects/cpplibrary/project.pro @@ -36,6 +36,11 @@ HEADERS += \\ %{GlobalHdrFileName} \\ @endif %{HdrFileName} +@if %{HasTranslation} + +TRANSLATIONS += \\ + %{TsFileName} +@endif @if %{IsQtPlugin} DISTFILES += %{PluginJsonFile} diff --git a/share/qtcreator/templates/wizards/projects/cpplibrary/project.qbs b/share/qtcreator/templates/wizards/projects/cpplibrary/project.qbs index 0e5df73e84..2c51c9e116 100644 --- a/share/qtcreator/templates/wizards/projects/cpplibrary/project.qbs +++ b/share/qtcreator/templates/wizards/projects/cpplibrary/project.qbs @@ -41,6 +41,9 @@ DynamicLibrary { @if %{IsQtPlugin} "%{PluginJsonFile}", @endif +@if %{HasTranslation} + "%{TsFileName}", +@endif ] @if '%{TargetInstallPath}' != '' diff --git a/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json b/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json index 8f4c264499..512ffdfe66 100644 --- a/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json +++ b/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json @@ -31,6 +31,7 @@ { "key": "TargetInstallPath", "value": "%{JS: value('IsShared') === 'true' ? '/usr/lib' : (value('IsQtPlugin') && value('PluginTargetPath') ? '$$[QT_INSTALL_PLUGINS]/' + value('PluginTargetPath') : '')}" }, { "key": "CN", "value": "%{JS: Cpp.className(value('Class'))}" }, { "key": "GUARD", "value": "%{JS: Cpp.classToHeaderGuard(value('Class'), Util.suffix(value('HdrFileName')))}" }, + { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" }, { "key": "GLOBAL_GUARD", "value": "%{JS: Cpp.headerGuard(value('GlobalHdrFileName'))}" } ], @@ -272,6 +273,12 @@ ] }, { + "trDisplayName": "Translation File", + "trShortTitle": "Translation", + "data": { "enabled": "%{JS: value('QtModule') === 'none' ? 'no' : 'yes'}" }, + "typeId": "QtTranslation" + }, + { "trDisplayName": "Kit Selection", "trShortTitle": "Kits", "typeId": "Kits", @@ -327,6 +334,11 @@ "condition": "%{JS: value('Type') === 'qtplugin'}" }, { + "source": "../translation.ts", + "target": "%{TsFileName}", + "condition": "%{HasTranslation}" + }, + { "source": "../git.ignore", "target": ".gitignore", "condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}" diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json index 6d734cb0e8..87cc5c0979 100644 --- a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json @@ -7,7 +7,7 @@ "trDisplayName": "Qt for Python - Empty", "trDisplayCategory": "Application", "icon": "icon.png", - "enabled": "%{JS: value('Plugins').indexOf('PythonEditor') >= 0}", + "enabled": "%{JS: value('Plugins').indexOf('Python') >= 0}", "featuresRequired": [ "QtSupport.Wizards.FeatureQt.5.6" ], "options": diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json index c8e397d0d8..eedad020e3 100644 --- a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json @@ -7,7 +7,7 @@ "trDisplayName": "Qt for Python - Window", "trDisplayCategory": "Application", "icon": "icon.png", - "enabled": "%{JS: value('Plugins').indexOf('PythonEditor') >= 0}", + "enabled": "%{JS: value('Plugins').indexOf('Python') >= 0}", "featuresRequired": [ "QtSupport.Wizards.FeatureQt.5.6" ], "options": diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/lib.png b/share/qtcreator/templates/wizards/projects/qtquick2-extension/lib.png Binary files differindex 0566f1d5f1..0566f1d5f1 100644 --- a/share/qtcreator/templates/wizards/qtquick2-extension/lib.png +++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/lib.png diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/lib@2x.png b/share/qtcreator/templates/wizards/projects/qtquick2-extension/lib@2x.png Binary files differindex 90a842d6e8..90a842d6e8 100644 --- a/share/qtcreator/templates/wizards/qtquick2-extension/lib@2x.png +++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/lib@2x.png diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/object.cpp b/share/qtcreator/templates/wizards/projects/qtquick2-extension/object.cpp index 15fe405242..a2288c47c1 100644 --- a/share/qtcreator/templates/wizards/qtquick2-extension/object.cpp +++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/object.cpp @@ -1,7 +1,7 @@ -#include "%ObjectName:l%.%CppHeaderSuffix%" +#include "%{ObjectHdr}" -%ObjectName%::%ObjectName%(QQuickItem *parent): - QQuickItem(parent) +%{ObjectName}::%{ObjectName}(QQuickItem *parent) + : QQuickItem(parent) { // By default, QQuickItem does not draw anything. If you subclass // QQuickItem to create a visual item, you will need to uncomment the @@ -10,6 +10,6 @@ // setFlag(ItemHasContents, true); } -%ObjectName%::~%ObjectName%() +%{ObjectName}::~%{ObjectName}() { } diff --git a/share/qtcreator/templates/wizards/projects/qtquick2-extension/object.h b/share/qtcreator/templates/wizards/projects/qtquick2-extension/object.h new file mode 100644 index 0000000000..e74c4233e8 --- /dev/null +++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/object.h @@ -0,0 +1,23 @@ +%{Cpp:LicenseTemplate}\ +@if '%{Cpp:PragmaOnce}' +#pragma once +@else +#ifndef %{OBJECTGUARD} +#define %{OBJECTGUARD} +@endif + +#include <QQuickItem> + +class %{ObjectName} : public QQuickItem +{ + Q_OBJECT + Q_DISABLE_COPY(%{ObjectName}) + +public: + explicit %{ObjectName}(QQuickItem *parent = nullptr); + ~%{ObjectName}() override; +}; + +@if ! '%{Cpp:PragmaOnce}' +#endif // %{OBJECTGUARD} +@endif diff --git a/share/qtcreator/templates/wizards/projects/qtquick2-extension/plugin.cpp b/share/qtcreator/templates/wizards/projects/qtquick2-extension/plugin.cpp new file mode 100644 index 0000000000..69afb9badd --- /dev/null +++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/plugin.cpp @@ -0,0 +1,12 @@ +#include "%{PluginHdr}" + +#include "%{ObjectHdr}" + +#include <qqml.h> + +void %{PluginName}::registerTypes(const char *uri) +{ + // @uri %{Uri} + qmlRegisterType<%{ObjectName}>(uri, 1, 0, "%{ObjectName}"); +} + diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/plugin.h b/share/qtcreator/templates/wizards/projects/qtquick2-extension/plugin.h index a7a18893ef..539aee0d5d 100644 --- a/share/qtcreator/templates/wizards/qtquick2-extension/plugin.h +++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/plugin.h @@ -1,13 +1,14 @@ +%{Cpp:LicenseTemplate}\ @if '%{Cpp:PragmaOnce}' #pragma once @else -#ifndef %ProjectName:h%_PLUGIN_H -#define %ProjectName:h%_PLUGIN_H +#ifndef %{PLUGINGUARD} +#define %{PLUGINGUARD} @endif #include <QQmlExtensionPlugin> -class %ProjectName:s%Plugin : public QQmlExtensionPlugin +class %{PluginName} : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) @@ -17,5 +18,5 @@ public: }; @if ! '%{Cpp:PragmaOnce}' -#endif // %ProjectName:h%_PLUGIN_H +#endif // %{PLUGINGUARD} @endif diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/project.pro b/share/qtcreator/templates/wizards/projects/qtquick2-extension/project.pro index b9677739e4..78d4325d32 100644 --- a/share/qtcreator/templates/wizards/qtquick2-extension/project.pro +++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/project.pro @@ -1,26 +1,26 @@ TEMPLATE = lib -TARGET = %ProjectName% +TARGET = %{ProjectName} QT += qml quick CONFIG += plugin c++11 TARGET = $$qtLibraryTarget($$TARGET) -uri = %Uri% +uri = %{Uri} # Input -SOURCES += \ - %ProjectName:l%_plugin.%CppSourceSuffix% \ - %ObjectName:l%.%CppSourceSuffix% +SOURCES += \\ + %{PluginSrc} \\ + %{ObjectSrc} -HEADERS += \ - %ProjectName:l%_plugin.%CppHeaderSuffix% \ - %ObjectName:l%.%CppHeaderSuffix% +HEADERS += \\ + %{PluginHdr} \\ + %{ObjectHdr} DISTFILES = qmldir !equals(_PRO_FILE_PWD_, $$OUT_PWD) { copy_qmldir.target = $$OUT_PWD/qmldir copy_qmldir.depends = $$_PRO_FILE_PWD_/qmldir - copy_qmldir.commands = $(COPY_FILE) \"$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)\" + copy_qmldir.commands = $(COPY_FILE) "$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)" "$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)" QMAKE_EXTRA_TARGETS += copy_qmldir PRE_TARGETDEPS += $$copy_qmldir.target } diff --git a/share/qtcreator/templates/wizards/projects/qtquick2-extension/qmldir b/share/qtcreator/templates/wizards/projects/qtquick2-extension/qmldir new file mode 100644 index 0000000000..8a3038ae48 --- /dev/null +++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/qmldir @@ -0,0 +1,2 @@ +module %{Uri} +plugin %{ProjectName} diff --git a/share/qtcreator/templates/wizards/projects/qtquick2-extension/wizard.json b/share/qtcreator/templates/wizards/projects/qtquick2-extension/wizard.json new file mode 100644 index 0000000000..b0f9e33ae3 --- /dev/null +++ b/share/qtcreator/templates/wizards/projects/qtquick2-extension/wizard.json @@ -0,0 +1,109 @@ +{ + "version": 1, + "supportedProjectTypes": [ "Qt4ProjectManager.Qt4Project" ], + "id": "M.QtQuick2ExtensionPlugin", + "category": "G.Library", + "trDescription": "Creates a C++ plugin to load Qt Quick extensions dynamically into applications using the QQmlEngine class.", + "trDisplayName": "Qt Quick 2 Extension Plugin", + "trDisplayCategory": "Library", + "icon": "lib.png", + "featuresRequired": [ "QtSupport.Wizards.FeatureQtQuick", "QtSupport.Wizards.FeatureQtQuick.2" ], + "enabled": "%{JS: value('Plugins').indexOf('QmakeProjectManager') >= 0}", + + "options": + [ + { "key": "ProjectFile", "value": "%{ProFile}" }, + { "key": "ProFile", "value": "%{JS: Util.fileName(value('ProjectDirectory') + '/' + value('ProjectName'), 'pro')}" }, + { "key": "PluginBaseFileName", "value": "%{JS: value('ProjectName') + '_plugin'}" }, + { "key": "PluginSrc", "value": "%{JS: Cpp.classToFileName(value('PluginBaseFileName'), Util.preferredSuffix('text/x-c++src'))}" }, + { "key": "PluginHdr", "value": "%{JS: Cpp.classToFileName(value('PluginBaseFileName'), Util.preferredSuffix('text/x-c++hdr'))}" }, + { "key": "ObjectSrc", "value": "%{JS: Cpp.classToFileName(value('ObjectName'), Util.preferredSuffix('text/x-c++src'))}" }, + { "key": "ObjectHdr", "value": "%{JS: Cpp.classToFileName(value('ObjectName'), Util.preferredSuffix('text/x-c++hdr'))}" }, + { "key": "PluginName", "value": "%{JS: value('ProjectName').charAt(0).toUpperCase() + value('ProjectName').slice(1) + 'Plugin' }" }, + { "key": "PLUGINGUARD", "value": "%{JS: Cpp.classToHeaderGuard(value('PluginBaseFileName'), Util.preferredSuffix('text/x-c++hdr'))}" }, + { "key": "OBJECTGUARD", "value": "%{JS: Cpp.classToHeaderGuard(value('ObjectName'), Util.preferredSuffix('text/x-c++hdr'))}" } + ], + + "pages": + [ + { + "trDisplayName": "Project Location", + "trShortTitle": "Location", + "typeId": "Project" + }, + { + "trDisplayName": "Custom Parameters", + "trShortTitle": "Details", + "typeId": "Fields", + "data": + [ + { + "name": "ObjectName", + "trDisplayName": "Object class-name:", + "mandatory": true, + "type": "LineEdit", + "data": + { + "validator": "^[A-Za-z0-9_]+$", + "trText": "MyItem" + } + }, + { + "name": "Uri", + "trDisplayName": "URI:", + "mandatory": true, + "type": "LineEdit", + "data": + { + "validator": "^[A-Za-z0-9]+([A-Za-z0-9-]*[A-Za-z0-9]+)?(\\.[A-Za-z0-9]+([-A-Za-z0-9]*[A-Za-z0-9]+)?)*$", + "trText": "com.mycompany.qmlcomponents" + } + } + ] + }, + { + "trDisplayName": "Project Management", + "trShortTitle": "Summary", + "typeId": "Summary" + } + ], + "generators": + [ + { + "typeId": "File", + "data": + [ + { + "source": "project.pro", + "target": "%{ProFile}", + "openAsProject": true + }, + { + "source": "qmldir", + "target": "qmldir" + }, + { + "source": "plugin.cpp", + "target": "%{PluginSrc}" + }, + { + "source": "plugin.h", + "target": "%{PluginHdr}" + }, + { + "source": "object.cpp", + "target": "%{ObjectSrc}" + }, + { + "source": "object.h", + "target": "%{ObjectHdr}" + }, + { + "source": "../git.ignore", + "target": ".gitignore", + "condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}" + } + ] + } + ] +} diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt b/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt index 165a32be3d..3678b3dcdb 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt @@ -11,18 +11,42 @@ set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) +@if %{HasTranslation} +find_package(Qt5 COMPONENTS Core Quick LinguistTools REQUIRED) + +set(TS_FILES %{TsFileName}) +@else find_package(Qt5 COMPONENTS Core Quick REQUIRED) +@endif if(ANDROID) - add_library(%{ProjectName} SHARED %{MainCppFileName} qml.qrc) + set(TARGET %{ProjectName}_${ANDROID_ABI}) + add_library(${TARGET} SHARED + %{MainCppFileName} + qml.qrc +@if %{HasTranslation} + ${TS_FILES} +@endif + ) else() - add_executable(%{ProjectName} %{MainCppFileName} qml.qrc) + set(TARGET %{ProjectName}) + add_executable(${TARGET} + %{MainCppFileName} + qml.qrc +@if %{HasTranslation} + ${TS_FILES} +@endif + ) endif() -target_compile_definitions(%{ProjectName} +target_compile_definitions(${TARGET} PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>) -target_link_libraries(%{ProjectName} +target_link_libraries(${TARGET} PRIVATE Qt5::Core Qt5::Quick) +@if %{HasTranslation} + +qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES}) +@endif # QtCreator supports the following variables for Android, which are identical to qmake Android variables. # Check http://doc.qt.io/qt-5/deployment-android.html for more information. diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/app.pro b/share/qtcreator/templates/wizards/projects/qtquickapplication/app.pro index 0ac5682b11..908aaa3e07 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/app.pro +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/app.pro @@ -21,6 +21,11 @@ SOURCES += \\ %{MainCppFileName} RESOURCES += qml.qrc +@if %{HasTranslation} + +TRANSLATIONS += \\ + %{TsFileName} +@endif # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/app.qbs b/share/qtcreator/templates/wizards/projects/qtquickapplication/app.qbs index 27a8b66c3c..f06fb39824 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/app.qbs +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/app.qbs @@ -29,6 +29,9 @@ Application { "%{MainCppFileName}", "main.qml", "qml.qrc", +@if %{HasTranslation} + "%{TsFileName}", +@endif ] Group { // Properties for the produced executable diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json index fe284df679..412aa3f8f8 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json @@ -22,6 +22,7 @@ { "key": "QtQuickVirtualKeyboardImport", "value": "%{JS: value('QtVersion').QtQuickVirtualKeyboardImport}" }, { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }, { "key": "UseVirtualKeyboardByDefault", "value": "%{JS: value('Plugins').indexOf('Boot2Qt') >= 0 || value('Plugins').indexOf('Boot2QtQdb') >= 0}" }, + { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" }, { "key": "SetQPAPhysicalSize", "value": "%{UseVirtualKeyboardByDefault}" } ], @@ -170,6 +171,11 @@ ] }, { + "trDisplayName": "Translation File", + "trShortTitle": "Translation", + "typeId": "QtTranslation" + }, + { "trDisplayName": "Kit Selection", "trShortTitle": "Kits", "typeId": "Kits", @@ -222,6 +228,11 @@ "source": "qml.qrc" }, { + "source": "../../translation.ts", + "target": "%{TsFileName}", + "condition": "%{HasTranslation}" + }, + { "source": "../../git.ignore", "target": ".gitignore", "condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}" diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/scroll/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/scroll/wizard.json index f03b62635a..adfa7def75 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/scroll/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/scroll/wizard.json @@ -24,6 +24,7 @@ { "key": "QtQuickControlsStyleTheme", "value": "%{JS: value('ControlsStyle').QtQuickControlsStyleTheme}" }, { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }, { "key": "UseVirtualKeyboardByDefault", "value": "%{JS: value('Plugins').indexOf('Boot2Qt') >= 0 || value('Plugins').indexOf('Boot2QtQdb') >= 0}" }, + { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" }, { "key": "SetQPAPhysicalSize", "value": "%{UseVirtualKeyboardByDefault}" } ], @@ -221,6 +222,11 @@ ] }, { + "trDisplayName": "Translation File", + "trShortTitle": "Translation", + "typeId": "QtTranslation" + }, + { "trDisplayName": "Kit Selection", "trShortTitle": "Kits", "typeId": "Kits", @@ -277,6 +283,11 @@ "source": "qml.qrc" }, { + "source": "../../translation.ts", + "target": "%{TsFileName}", + "condition": "%{HasTranslation}" + }, + { "source": "../../git.ignore", "target": ".gitignore", "condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}" diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/stack/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/stack/wizard.json index 6640901abe..a4593f8eb1 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/stack/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/stack/wizard.json @@ -24,6 +24,7 @@ { "key": "QtQuickControlsStyleTheme", "value": "%{JS: value('ControlsStyle').QtQuickControlsStyleTheme}" }, { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }, { "key": "UseVirtualKeyboardByDefault", "value": "%{JS: value('Plugins').indexOf('Boot2Qt') >= 0 || value('Plugins').indexOf('Boot2QtQdb') >= 0}" }, + { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" }, { "key": "SetQPAPhysicalSize", "value": "%{UseVirtualKeyboardByDefault}" } ], @@ -239,6 +240,11 @@ ] }, { + "trDisplayName": "Translation File", + "trShortTitle": "Translation", + "typeId": "QtTranslation" + }, + { "trDisplayName": "Kit Selection", "trShortTitle": "Kits", "typeId": "Kits", @@ -307,6 +313,11 @@ "source": "qml.qrc" }, { + "source": "../../translation.ts", + "target": "%{TsFileName}", + "condition": "%{HasTranslation}" + }, + { "source": "../../git.ignore", "target": ".gitignore", "condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}" diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/swipe/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/swipe/wizard.json index 2b6ac53030..9f47b864e1 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/swipe/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/swipe/wizard.json @@ -24,6 +24,7 @@ { "key": "QtQuickControlsStyleTheme", "value": "%{JS: value('ControlsStyle').QtQuickControlsStyleTheme}" }, { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }, { "key": "UseVirtualKeyboardByDefault", "value": "%{JS: value('Plugins').indexOf('Boot2Qt') >= 0 || value('Plugins').indexOf('Boot2QtQdb') >= 0}" }, + { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" }, { "key": "SetQPAPhysicalSize", "value": "%{UseVirtualKeyboardByDefault}" } ], @@ -239,6 +240,11 @@ ] }, { + "trDisplayName": "Translation File", + "trShortTitle": "Translation", + "typeId": "QtTranslation" + }, + { "trDisplayName": "Kit Selection", "trShortTitle": "Kits", "typeId": "Kits", @@ -303,6 +309,11 @@ "source": "qml.qrc" }, { + "source": "../../translation.ts", + "target": "%{TsFileName}", + "condition": "%{HasTranslation}" + }, + { "source": "../../git.ignore", "target": ".gitignore", "condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}" diff --git a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/CMakeLists.txt b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/CMakeLists.txt index 5fd51e9014..ea825062f4 100644 --- a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/CMakeLists.txt +++ b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/CMakeLists.txt @@ -11,7 +11,13 @@ set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) +@if %{HasTranslation} +find_package(Qt5 COMPONENTS Widgets LinguistTools REQUIRED) + +set(TS_FILES %{TsFileName}) +@else find_package(Qt5 COMPONENTS Widgets REQUIRED) +@endif add_executable(%{ProjectName} %{MainFileName} @@ -20,6 +26,13 @@ add_executable(%{ProjectName} @if %{GenerateForm} %{FormFileName} @endif +@if %{HasTranslation} + ${TS_FILES} +@endif ) target_link_libraries(%{ProjectName} PRIVATE Qt5::Widgets) +@if %{HasTranslation} + +qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES}) +@endif diff --git a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.pro b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.pro index a5362aa9bc..a0a237bf20 100644 --- a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.pro +++ b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.pro @@ -26,6 +26,11 @@ HEADERS += \\ FORMS += \\ %{FormFileName} @endif +@if %{HasTranslation} + +TRANSLATIONS += \\ + %{TsFileName} +@endif # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin diff --git a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.qbs b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.qbs index 4a54380d6b..baa6326cb8 100644 --- a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.qbs +++ b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/project.qbs @@ -19,9 +19,12 @@ QtApplication { "%{MainFileName}", "%{SrcFileName}", "%{HdrFileName}", - @if %{GenerateForm} +@if %{GenerateForm} "%{FormFileName}", - @endif +@endif +@if %{HasTranslation} + "%{TsFileName}", +@endif ] install: true diff --git a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/wizard.json b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/wizard.json index 9cce84a413..971ef3f88f 100644 --- a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/wizard.json @@ -19,6 +19,7 @@ { "key": "MainFileName", "value": "%{JS: 'main.' + Util.preferredSuffix('text/x-c++src')}" }, { "key": "UiHdrFileName", "value": "%{JS: (value('BuildSystem') === 'cmake' ? (Util.path(value('FormFileName')) + '/') : '') + 'ui_' + Util.completeBaseName(value('FormFileName')) + '.h'}" }, { "key": "CN", "value": "%{JS: Cpp.className(value('Class'))}" }, + { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" }, { "key": "GUARD", "value": "%{JS: Cpp.classToHeaderGuard(value('Class'), Util.suffix(value('HdrFileName')))}" } ], @@ -140,6 +141,11 @@ ] }, { + "trDisplayName": "Translation File", + "trShortTitle": "Translation", + "typeId": "QtTranslation" + }, + { "trDisplayName": "Kit Selection", "trShortTitle": "Kits", "typeId": "Kits", @@ -194,6 +200,11 @@ "condition": "%{GenerateForm}" }, { + "source": "../translation.ts", + "target": "%{TsFileName}", + "condition": "%{HasTranslation}" + }, + { "source": "../git.ignore", "target": ".gitignore", "condition": "%{JS: !value('IsSubproject') && value('VersionControl') === 'G.Git'}" diff --git a/share/qtcreator/templates/wizards/projects/translation.ts b/share/qtcreator/templates/wizards/projects/translation.ts new file mode 100644 index 0000000000..ed21a4017e --- /dev/null +++ b/share/qtcreator/templates/wizards/projects/translation.ts @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.1" language="%{TsLanguage}"></TS> diff --git a/share/qtcreator/templates/wizards/projects/vcs/bazaar/wizard.json b/share/qtcreator/templates/wizards/projects/vcs/bazaar/wizard.json index f81509c4ed..060b55944a 100644 --- a/share/qtcreator/templates/wizards/projects/vcs/bazaar/wizard.json +++ b/share/qtcreator/templates/wizards/projects/vcs/bazaar/wizard.json @@ -40,7 +40,9 @@ "name": "Repo", "trDisplayName": "Repository:", "mandatory": true, - "type": "LineEdit" + "type": "LineEdit", + "isComplete": "%{JS: Vcs.isValidRepoUrl('%{vcsId}', '%{Repo}')}", + "trIncompleteMessage": "Repository URL is not valid" }, { "name": "Sp1", diff --git a/share/qtcreator/templates/wizards/projects/vcs/cvs/icon.png b/share/qtcreator/templates/wizards/projects/vcs/cvs/icon.png Binary files differindex bc452165a7..bd925b2e98 100644 --- a/share/qtcreator/templates/wizards/projects/vcs/cvs/icon.png +++ b/share/qtcreator/templates/wizards/projects/vcs/cvs/icon.png diff --git a/share/qtcreator/templates/wizards/projects/vcs/cvs/icon@2x.png b/share/qtcreator/templates/wizards/projects/vcs/cvs/icon@2x.png Binary files differindex c29386c5e4..ec330c9f44 100644 --- a/share/qtcreator/templates/wizards/projects/vcs/cvs/icon@2x.png +++ b/share/qtcreator/templates/wizards/projects/vcs/cvs/icon@2x.png diff --git a/share/qtcreator/templates/wizards/projects/vcs/cvs/wizard.json b/share/qtcreator/templates/wizards/projects/vcs/cvs/wizard.json index 10969e3da8..075a69fdb1 100644 --- a/share/qtcreator/templates/wizards/projects/vcs/cvs/wizard.json +++ b/share/qtcreator/templates/wizards/projects/vcs/cvs/wizard.json @@ -38,7 +38,9 @@ "name": "Repo", "trDisplayName": "Module:", "mandatory": true, - "type": "LineEdit" + "type": "LineEdit", + "isComplete": "%{JS: Vcs.isValidRepoUrl('%{vcsId}', '%{Repo}')}", + "trIncompleteMessage": "Repository URL is not valid" }, { "name": "Sp1", diff --git a/share/qtcreator/templates/wizards/projects/vcs/git/icon.png b/share/qtcreator/templates/wizards/projects/vcs/git/icon.png Binary files differindex 46bcd4aab5..cfbd0c497f 100644 --- a/share/qtcreator/templates/wizards/projects/vcs/git/icon.png +++ b/share/qtcreator/templates/wizards/projects/vcs/git/icon.png diff --git a/share/qtcreator/templates/wizards/projects/vcs/git/icon@2x.png b/share/qtcreator/templates/wizards/projects/vcs/git/icon@2x.png Binary files differindex cca3e6ac0d..2edb04b5a0 100644 --- a/share/qtcreator/templates/wizards/projects/vcs/git/icon@2x.png +++ b/share/qtcreator/templates/wizards/projects/vcs/git/icon@2x.png diff --git a/share/qtcreator/templates/wizards/projects/vcs/git/wizard.json b/share/qtcreator/templates/wizards/projects/vcs/git/wizard.json index 0295468f6f..401be45a75 100644 --- a/share/qtcreator/templates/wizards/projects/vcs/git/wizard.json +++ b/share/qtcreator/templates/wizards/projects/vcs/git/wizard.json @@ -39,7 +39,9 @@ { "name": "Repo", "trDisplayName": "Repository:", - "type": "LineEdit" + "type": "LineEdit", + "isComplete": "%{JS: Vcs.isValidRepoUrl('%{vcsId}', '%{Repo}')}", + "trIncompleteMessage": "Repository URL is not valid" }, { "name": "Branch", diff --git a/share/qtcreator/templates/wizards/projects/vcs/mercurial/wizard.json b/share/qtcreator/templates/wizards/projects/vcs/mercurial/wizard.json index 8e655e1eb6..81fa26da04 100644 --- a/share/qtcreator/templates/wizards/projects/vcs/mercurial/wizard.json +++ b/share/qtcreator/templates/wizards/projects/vcs/mercurial/wizard.json @@ -39,7 +39,9 @@ "name": "Repo", "trDisplayName": "Repository:", "mandatory": true, - "type": "LineEdit" + "type": "LineEdit", + "isComplete": "%{JS: Vcs.isValidRepoUrl('%{vcsId}', '%{Repo}')}", + "trIncompleteMessage": "Repository URL is not valid" }, { "name": "Sp1", diff --git a/share/qtcreator/templates/wizards/projects/vcs/subversion/wizard.json b/share/qtcreator/templates/wizards/projects/vcs/subversion/wizard.json index cfeddbb532..2e63b12eb4 100644 --- a/share/qtcreator/templates/wizards/projects/vcs/subversion/wizard.json +++ b/share/qtcreator/templates/wizards/projects/vcs/subversion/wizard.json @@ -39,7 +39,9 @@ "name": "Repo", "trDisplayName": "Repository:", "mandatory": true, - "type": "LineEdit" + "type": "LineEdit", + "isComplete": "%{JS: Vcs.isValidRepoUrl('%{vcsId}', '%{Repo}')}", + "trIncompleteMessage": "Repository URL is not valid" }, { "name": "Sp1", diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/object.h b/share/qtcreator/templates/wizards/qtquick2-extension/object.h deleted file mode 100644 index cabd5229db..0000000000 --- a/share/qtcreator/templates/wizards/qtquick2-extension/object.h +++ /dev/null @@ -1,22 +0,0 @@ -@if '%{Cpp:PragmaOnce}' -#pragma once -@else -#ifndef %ObjectName:u%_H -#define %ObjectName:u%_H -@endif - -#include <QQuickItem> - -class %ObjectName% : public QQuickItem -{ - Q_OBJECT - Q_DISABLE_COPY(%ObjectName%) - -public: - explicit %ObjectName%(QQuickItem *parent = nullptr); - ~%ObjectName%() override; -}; - -@if ! '%{Cpp:PragmaOnce}' -#endif // %ObjectName:u%_H -@endif diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/plugin.cpp b/share/qtcreator/templates/wizards/qtquick2-extension/plugin.cpp deleted file mode 100644 index c4ff1b1732..0000000000 --- a/share/qtcreator/templates/wizards/qtquick2-extension/plugin.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "%ProjectName:l%_plugin.%CppHeaderSuffix%" -#include "%ObjectName:l%.%CppHeaderSuffix%" - -#include <qqml.h> - -void %ProjectName:s%Plugin::registerTypes(const char *uri) -{ - // @uri %Uri% - qmlRegisterType<%ObjectName%>(uri, 1, 0, "%ObjectName:c%"); -} - diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/qmldir b/share/qtcreator/templates/wizards/qtquick2-extension/qmldir deleted file mode 100644 index f1f54802f3..0000000000 --- a/share/qtcreator/templates/wizards/qtquick2-extension/qmldir +++ /dev/null @@ -1,2 +0,0 @@ -module %Uri% -plugin %ProjectName% diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/wizard.xml b/share/qtcreator/templates/wizards/qtquick2-extension/wizard.xml deleted file mode 100644 index 2c3a288c0c..0000000000 --- a/share/qtcreator/templates/wizards/qtquick2-extension/wizard.xml +++ /dev/null @@ -1,66 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -Custom project wizard configuration example file. Note that by convention, -the project file goes last. -The "class" and "firstpage" attributes specify that it is a Qt 4 wizard and -leave room for the Qt 4 target page. ---> -<wizard version="1" kind="project" - class="qmakeproject" firstpage="10" - id="QtQuick2ExtensionPlugin" category="G.Library" - featuresRequired="QtSupport.Wizards.FeatureQtQuick,QtSupport.Wizards.FeatureQtQuick.2"> - <icon>lib.png</icon> - <description>Creates a C++ plugin to load extensions dynamically into applications using the QQmlEngine class. Requires Qt 5.0 or newer.</description> - <displayname>Qt Quick 2 Extension Plugin</displayname> - <displaycategory>Library</displaycategory> - <files> - <file source="qmldir" target="qmldir"/> - <file source="plugin.h" target="%ProjectName:l%_plugin.%CppHeaderSuffix%"/> - <file source="plugin.cpp" target="%ProjectName:l%_plugin.%CppSourceSuffix%"/> - <file source="object.h" target="%ObjectName:l%.%CppHeaderSuffix%"/> - <file source="object.cpp" target="%ObjectName:l%.%CppSourceSuffix%" openeditor="true"/> - <file source="project.pro" target="%ProjectName:l%.pro" openproject="true"/> - </files> - <!-- Create a 2nd wizard page with parameters --> - <fieldpagetitle>Custom QML Extension Plugin Parameters</fieldpagetitle> - <fields> - <field mandatory="true" name="ObjectName"> - <fieldcontrol class="QLineEdit" validator='^[A-Za-z0-9_]+$' defaulttext="MyItem"/> - <fielddescription>Object class-name:</fielddescription> - </field> - <field mandatory="true" name="Uri"> - <fieldcontrol class="QLineEdit" validator='^[A-Za-z0-9]+([A-Za-z0-9-]*[A-Za-z0-9]+)?(\.[A-Za-z0-9]+([-A-Za-z0-9]*[A-Za-z0-9]+)?)*$' defaulttext="com.mycompany.qmlcomponents"/> - <fielddescription>URI:</fielddescription> - </field> - </fields> - <validationrules> - <validationrule condition='"%ObjectName%" != "%ProjectName%_plugin"'> - <message>The project name and the object class-name cannot be the same.</message> - </validationrule> - </validationrules> -</wizard> diff --git a/share/qtcreator/translations/CMakeLists.txt b/share/qtcreator/translations/CMakeLists.txt new file mode 100644 index 0000000000..dfa5da1238 --- /dev/null +++ b/share/qtcreator/translations/CMakeLists.txt @@ -0,0 +1,214 @@ +set(languages cs da de fr ja pl ru sl uk zh_CN zh_TW) +set(bad_languages hu) # Fix these before including them in languages! + +find_package(PythonInterp) + +set(json_wizards_h "") +set(custom_wizards_h "") +set(externaltools_h "") +set(snippets_h "") + +if (NOT PYTHONINTERP_FOUND OR NOT PYTHON_VERSION_STRING VERSION_GREATER_EQUAL "3.0.0") + message(WARNING "No python3 interpreter found, skipping extraction of data from XML and JSON files.\n *** Please pass -DPYTHON_EXECUTABLE=/path/to/python3 to cmake.") +else() + set(json_wizards_h "${CMAKE_CURRENT_BINARY_DIR}/jsonwizards_tr.h") + add_custom_command(OUTPUT "${json_wizards_h}" + COMMAND "${PYTHON_EXECUTABLE}" + "${CMAKE_CURRENT_SOURCE_DIR}/extract-jsonwizards.py" + "${PROJECT_SOURCE_DIR}/share/qtcreator/templates/wizards" "${json_wizards_h}" + COMMENT Generate translation data from JSON wizards + VERBATIM) + + set(custom_wizards_h "${CMAKE_CURRENT_BINARY_DIR}/customwizards_tr.h") + add_custom_command(OUTPUT "${custom_wizards_h}" + COMMAND "${PYTHON_EXECUTABLE}" + "${CMAKE_CURRENT_SOURCE_DIR}/extract-customwizards.py" + "${PROJECT_SOURCE_DIR}/share/qtcreator/templates/wizards" "${custom_wizards_h}" + COMMENT Generate translation data from XML wizards + VERBATIM) + + set(externaltools_h "${CMAKE_CURRENT_BINARY_DIR}/externaltools_tr.h") + add_custom_command(OUTPUT "${externaltools_h}" + COMMAND "${PYTHON_EXECUTABLE}" + "${CMAKE_CURRENT_SOURCE_DIR}/extract-externaltools.py" + "${PROJECT_SOURCE_DIR}/src/share/qtcreator/externaltools" "${externaltools_h}" + COMMENT Generate translation data from external tools definitions + VERBATIM) + + set(snippets_h "${CMAKE_CURRENT_BINARY_DIR}/snippets_tr.h") + add_custom_command(OUTPUT "${snippets_h}" + COMMAND "${PYTHON_EXECUTABLE}" + "${CMAKE_CURRENT_SOURCE_DIR}/extract-snippets.py" + "${PROJECT_SOURCE_DIR}/share/qtcreator/snippets" "${snippets_h}" + COMMENT Generate translation data from snippets definitions + VERBATIM) +endif() + +function(_extract_ts_data_from_targets outprefix) + set(_sources "") + set(_includes "") + + set(_targets "${ARGN}") + list(REMOVE_DUPLICATES _targets) + + foreach(t IN ITEMS ${_targets}) + if (TARGET "${t}") + get_target_property(_skip_translation "${t}" QT_SKIP_TRANSLATION) + get_target_property(_source_dir "${t}" SOURCE_DIR) + get_target_property(_interface_include_dirs "${t}" INTERFACE_INCLUDE_DIRECTORIES) + get_target_property(_include_dirs "${t}" INCLUDE_DIRECTORIES) + get_target_property(_source_files "${t}" SOURCES) + get_target_property(_extra_translations "${t}" QT_EXTRA_TRANSLATIONS) + + if (NOT _skip_translation) + if(_include_dirs) + list(APPEND _includes ${_include_dirs}) + endif() + + if(_interface_include_dirs) + list(APPEND _interface_includes ${_include_dirs}) + endif() + + set(_target_sources "") + if(_source_files) + list(APPEND _target_sources ${_source_files}) + endif() + if(_extra_translations) + list(APPEND _target_sources ${_extra_translations}) + endif() + foreach(s IN ITEMS ${_target_sources}) + get_filename_component(_abs_source "${s}" ABSOLUTE BASE_DIR "${_source_dir}") + list(APPEND _sources "${_abs_source}") + endforeach() + endif() + endif() + endforeach() + + set("${outprefix}_sources" "${_sources}" PARENT_SCOPE) + set("${outprefix}_includes" "${_includes}" PARENT_SCOPE) +endfunction() + +function(_create_ts_custom_target name) + cmake_parse_arguments(_arg "" "FILE_PREFIX;TS_TARGET_PREFIX" "LANGUAGES;SOURCES;INCLUDES" ${ARGN}) + if (_arg_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Invalid parameters to _create_ts_custom_target: ${_arg_UNPARSED_ARGUMENTS}.") + endif() + + if (NOT _arg_TS_TARGET_PREFIX) + set(_arg_TS_TARGET_PREFIX "ts_") + endif() + + set(ts_languages ${_arg_LANGUAGES}) + if (NOT ts_languages) + set(ts_languages "${name}") + endif() + + foreach(l IN ITEMS ${ts_languages}) + list(APPEND ts_files "${CMAKE_CURRENT_SOURCE_DIR}/${_arg_FILE_PREFIX}_${l}.ts") + endforeach() + + set(_sources "${_arg_SOURCES}") + list(SORT _sources) + + set(_includes "${_arg_INCLUDES}") + + list(REMOVE_DUPLICATES _sources) + list(REMOVE_DUPLICATES _includes) + + list(REMOVE_ITEM _sources "") + list(REMOVE_ITEM _includes "") + + set(_prepended_includes) + foreach(include IN LISTS _includes) + list(APPEND _prepended_includes "-I${include}") + endforeach() + set(_includes "${_prepended_includes}") + + string(REPLACE ";" "\n" _sources_str "${_sources}") + string(REPLACE ";" "\n" _includes_str "${_includes}") + + set(ts_file_list "${CMAKE_CURRENT_BINARY_DIR}/ts_${name}.lst") + file(WRITE "${ts_file_list}" "${_sources_str}\n${_includes_str}\n") + + add_custom_target("${_arg_TS_TARGET_PREFIX}${name}" + COMMAND Qt5::lupdate -locations relative -no-ui-lines -no-sort "@${ts_file_list}" -ts ${ts_files} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Generate .ts files" + DEPENDS ${_sources} + VERBATIM) +endfunction() + +function(add_translation_targets file_prefix) + if (NOT TARGET Qt5::lrelease) + # No Qt translation tools were found: Skip this directory + message(WARNING "No Qt translation tools found, skipping translation targets. Add find_package(Qt5 COMPONENTS LinguistTools) to CMake to enable.") + return() + endif() + + cmake_parse_arguments(_arg "" + "OUTPUT_DIRECTORY;INSTALL_DESTINATION;TS_TARGET_PREFIX;QM_TARGET_PREFIX;ALL_QM_TARGET" + "LANGUAGES;TARGETS;SOURCES;INCLUDES" ${ARGN}) + if (_arg_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Invalid parameters to add_translation_targets: ${_arg_UNPARSED_ARGUMENTS}.") + endif() + + if (NOT _arg_TS_TARGET_PREFIX) + set(_arg_TS_TARGET_PREFIX "ts_") + endif() + + if (NOT _arg_QM_TARGET_PREFIX) + set(_arg_QM_TARGET_PREFIX "generate_qm_file_") + endif() + + if (NOT _arg_ALL_QM_TARGET) + set(_arg_ALL_QM_TARGET "generate_qm_files") + endif() + + if (NOT _arg_OUTPUT_DIRECTORY) + set(_arg_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + endif() + + if (NOT _arg_INSTALL_DESTINATION) + message(FATAL_ERROR "Please provide a INSTALL_DESTINATION to add_translation_targets") + endif() + + _extract_ts_data_from_targets(_to_process "${_arg_TARGETS}") + + _create_ts_custom_target(untranslated + FILE_PREFIX "${file_prefix}" TS_TARGET_PREFIX "${_arg_TS_TARGET_PREFIX}" + SOURCES ${_to_process_sources} ${_arg_SOURCES} INCLUDES ${_to_process_includes} ${_arg_INCLUDES}) + + if (NOT TARGET "${_arg_ALL_QM_TARGET}") + add_custom_target("${_arg_ALL_QM_TARGET}" ALL COMMENT "Generate .qm-files") + endif() + + foreach(l IN ITEMS ${_arg_LANGUAGES}) + set(_ts_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_prefix}_${l}.ts") + set(_qm_file "${_arg_OUTPUT_DIRECTORY}/${file_prefix}_${l}.qm") + + _create_ts_custom_target("${l}" FILE_PREFIX "${file_prefix}" TS_TARGET_PREFIX "${_arg_TS_TARGET_PREFIX}" + SOURCES ${_to_process_sources} ${_arg_SOURCES} INCLUDES ${_to_process_includes} ${_arg_INCLUDES}) + + add_custom_command(OUTPUT "${_qm_file}" + COMMAND Qt5::lrelease "${_ts_file}" -qm "${_qm_file}" + MAIN_DEPENDENCY "${_ts_file}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Generate .qm file" + VERBATIM) + add_custom_target("${_arg_QM_TARGET_PREFIX}${l}" DEPENDS "${_qm_file}") + install(FILES "${_qm_file}" DESTINATION ${_arg_INSTALL_DESTINATION}) + + add_dependencies("${_arg_ALL_QM_TARGET}" "${_arg_QM_TARGET_PREFIX}${l}") + endforeach() + + _create_ts_custom_target(all LANGUAGES ${_arg_LANGUAGES} FILE_PREFIX "${file_prefix}" + SOURCES ${_to_process_sources} ${_arg_SOURCES} INCLUDES ${_to_process_includes} ${_arg_INCLUDES}) +endfunction() + +### collect targets to include in documentation: +add_translation_targets(qtcreator + LANGUAGES ${languages} + OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${IDE_DATA_PATH}/translations" + INSTALL_DESTINATION "${IDE_DATA_PATH}/translations" + TARGETS "${__QTC_LIBRARIES}" "${__QTC_PLUGINS}" + SOURCES "${json_wizards_h}" "${custom_wizards_h}" "${externaltools_h}" "${snippets_h}") diff --git a/share/qtcreator/translations/extract-customwizards.py b/share/qtcreator/translations/extract-customwizards.py new file mode 100644 index 0000000000..14b7ddcf33 --- /dev/null +++ b/share/qtcreator/translations/extract-customwizards.py @@ -0,0 +1,67 @@ +#!/usr/bin/python +############################################################################ +# +# Copyright (C) 2019 The Qt Company Ltd. +# Contact: https://www.qt.io/licensing/ +# +# This file is part of Qt Creator. +# +# Commercial License Usage +# Licensees holding valid commercial Qt licenses may use this file in +# accordance with the commercial license agreement provided with the +# Software or, alternatively, in accordance with the terms contained in +# a written agreement between you and The Qt Company. For licensing terms +# and conditions see https://www.qt.io/terms-conditions. For further +# information use the contact form at https://www.qt.io/contact-us. +# +# GNU General Public License Usage +# Alternatively, this file may be used under the terms of the GNU +# General Public License version 3 as published by the Free Software +# Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +# included in the packaging of this file. Please review the following +# information to ensure the GNU General Public License requirements will +# be met: https://www.gnu.org/licenses/gpl-3.0.html. +# +############################################################################ + +import os +import sys +import xml.etree.ElementTree as ET + +if len(sys.argv) != 3: + print("Please provide a top level directory to scan and a file to write into.") + sys.exit(1) + +top_dir = sys.argv[1] +target_file = sys.argv[2] + + +def fix_value(value): + value = value.replace('\"', '\\\"') + value = value.replace('\n', '\\\n') + return value + + +def parse_file(file_path): + root = ET.parse(file_path).getroot() + result = '' + + for i in ['.//description', './/displayname', './/displaycategory', + './/fieldpagetitle', './/fielddescription', + './/comboentrytext', + './/message']: + for e in root.findall(i): + result += 'QT_TRANSLATE_NOOP("ProjectExplorer::CustomWizard", "{}"); // {}\n'.format(fix_value(e.text), file_path) + + return result + +result = '' + +# traverse root directory, and list directories as dirs and files as files +for root, _, files in os.walk(top_dir): + for file in files: + if file == "wizard.xml": + result += parse_file(os.path.join(root, file)) + +with open(target_file, 'w') as header_file: + header_file.write(result) diff --git a/share/qtcreator/translations/extract-externaltools.py b/share/qtcreator/translations/extract-externaltools.py new file mode 100644 index 0000000000..ad4d19a844 --- /dev/null +++ b/share/qtcreator/translations/extract-externaltools.py @@ -0,0 +1,64 @@ +#!/usr/bin/python +############################################################################ +# +# Copyright (C) 2019 The Qt Company Ltd. +# Contact: https://www.qt.io/licensing/ +# +# This file is part of Qt Creator. +# +# Commercial License Usage +# Licensees holding valid commercial Qt licenses may use this file in +# accordance with the commercial license agreement provided with the +# Software or, alternatively, in accordance with the terms contained in +# a written agreement between you and The Qt Company. For licensing terms +# and conditions see https://www.qt.io/terms-conditions. For further +# information use the contact form at https://www.qt.io/contact-us. +# +# GNU General Public License Usage +# Alternatively, this file may be used under the terms of the GNU +# General Public License version 3 as published by the Free Software +# Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +# included in the packaging of this file. Please review the following +# information to ensure the GNU General Public License requirements will +# be met: https://www.gnu.org/licenses/gpl-3.0.html. +# +############################################################################ + +import os +import sys +import xml.etree.ElementTree as ET + +if len(sys.argv) != 3: + print("Please provide a top level directory to scan and a file to write into.") + sys.exit(1) + +top_dir = sys.argv[1] +target_file = sys.argv[2] + + +def fix_value(value): + value = value.replace('\"', '\\\"') + value = value.replace('\n', '\\\n') + return value + + +def parse_file(file_path): + root = ET.parse(file_path).getroot() + result = '' + + for i in ['.//description', './/displayname', './/category']: + for e in root.findall(i): + result += 'QT_TRANSLATE_NOOP("Core::Internal::ExternalTool", "{}"); // {}\n'.format(fix_value(e.text), file_path) + + return result + +result = '' + +# traverse root directory, and list directories as dirs and files as files +for root, _, files in os.walk(top_dir): + for file in files: + if file.endswith('.xml'): + result += parse_file(os.path.join(root, file)) + +with open(target_file, 'w') as header_file: + header_file.write(result) diff --git a/share/qtcreator/translations/extract-jsonwizards.py b/share/qtcreator/translations/extract-jsonwizards.py new file mode 100644 index 0000000000..8242481131 --- /dev/null +++ b/share/qtcreator/translations/extract-jsonwizards.py @@ -0,0 +1,81 @@ +#!/usr/bin/python +############################################################################ +# +# Copyright (C) 2019 The Qt Company Ltd. +# Contact: https://www.qt.io/licensing/ +# +# This file is part of Qt Creator. +# +# Commercial License Usage +# Licensees holding valid commercial Qt licenses may use this file in +# accordance with the commercial license agreement provided with the +# Software or, alternatively, in accordance with the terms contained in +# a written agreement between you and The Qt Company. For licensing terms +# and conditions see https://www.qt.io/terms-conditions. For further +# information use the contact form at https://www.qt.io/contact-us. +# +# GNU General Public License Usage +# Alternatively, this file may be used under the terms of the GNU +# General Public License version 3 as published by the Free Software +# Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +# included in the packaging of this file. Please review the following +# information to ensure the GNU General Public License requirements will +# be met: https://www.gnu.org/licenses/gpl-3.0.html. +# +############################################################################ + +import os +import sys +import json + +if len(sys.argv) != 3: + print("Please provide a top level directory to scan and a file to write into.") + sys.exit(1) + +top_dir = sys.argv[1] +target_file = sys.argv[2] + + +def recursive_iter(obj, key=''): + if isinstance(obj, dict): + for k in sorted(obj.keys()): + yield from recursive_iter(obj[k], k) + elif isinstance(obj, tuple): + for item in obj: + yield from recursive_iter(item, '') + elif isinstance(obj, list): + for item in obj: + yield from recursive_iter(item, '') + else: + yield key, obj + + +def fix_value(value): + value = value.replace('\"', '\\\"') + value = value.replace('\n', '\\\n') + return value + + +def parse_file(file_path): + root = '' + result = '' + + with open(file_path) as f: + root = json.load(f) + + for key, value in recursive_iter(root): + if key.startswith('tr'): + result += 'QT_TRANSLATE_NOOP("ProjectExplorer::JsonWizard", "{}"); // {}\n'.format(fix_value(value), file_path) + + return result + +result = '// This file is autogenerated\n' + +# traverse root directory, and list directories as dirs and files as files +for root, _, files in os.walk(top_dir): + for file in files: + if file == "wizard.json": + result += parse_file(os.path.join(root, file)) + +with open(target_file, 'w') as header_file: + header_file.write(result) diff --git a/share/qtcreator/translations/extract-snippets.py b/share/qtcreator/translations/extract-snippets.py new file mode 100644 index 0000000000..2c393024a6 --- /dev/null +++ b/share/qtcreator/translations/extract-snippets.py @@ -0,0 +1,65 @@ +#!/usr/bin/python +############################################################################ +# +# Copyright (C) 2019 The Qt Company Ltd. +# Contact: https://www.qt.io/licensing/ +# +# This file is part of Qt Creator. +# +# Commercial License Usage +# Licensees holding valid commercial Qt licenses may use this file in +# accordance with the commercial license agreement provided with the +# Software or, alternatively, in accordance with the terms contained in +# a written agreement between you and The Qt Company. For licensing terms +# and conditions see https://www.qt.io/terms-conditions. For further +# information use the contact form at https://www.qt.io/contact-us. +# +# GNU General Public License Usage +# Alternatively, this file may be used under the terms of the GNU +# General Public License version 3 as published by the Free Software +# Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +# included in the packaging of this file. Please review the following +# information to ensure the GNU General Public License requirements will +# be met: https://www.gnu.org/licenses/gpl-3.0.html. +# +############################################################################ + +import os +import sys +import xml.etree.ElementTree as ET + +if len(sys.argv) != 3: + print("Please provide a top level directory to scan and a file to write into.") + sys.exit(1) + +top_dir = sys.argv[1] +target_file = sys.argv[2] + + +def fix_value(value): + value = value.replace('\"', '\\\"') + value = value.replace('\n', '\\\n') + return value + + +def parse_file(file_path): + root = ET.parse(file_path).getroot() + result = '' + + for e in root.findall('snippet'): + if 'complement' in e.attrib: + result += 'QT_TRANSLATE_NOOP3("TextEditor::Internal::Snippets", "{}", "group:\'{}\' trigger:\'{}\'"); // {}\n' \ + .format(fix_value(e.attrib['complement']), e.attrib['group'], e.attrib['trigger'], file_path) + + return result + +result = '' + +# traverse root directory, and list directories as dirs and files as files +for root, _, files in os.walk(top_dir): + for file in files: + if file.endswith('.xml'): + result += parse_file(os.path.join(root, file)) + +with open(target_file, 'w') as header_file: + header_file.write(result) |