Merge with develop

--HG--
branch : feature
This commit is contained in:
Valentina Zhuravska 2016-06-01 20:44:50 +03:00
commit 12ae761527
273 changed files with 8226 additions and 2009 deletions

View file

@ -23,11 +23,16 @@
- [#478] Rename 'Print preview tiled' to 'Preview Tiled PDF'.
- [#472] Add 'Full Name' column to Formula dialog.
- [#487] True dart point always goes to origin when the label is moved.
- [#128] New Tool: Slash and Spread.
- [#409] New feature: Export measurement file to Excel .csv.
# Version 0.4.5
- [#435] Valentina doesn't change the cursor.
- [#473] Tape 'Preferences' cause loss of focus.
- [#485] Error when drawing a curved path.
- [#491] Valentina doesn't update fractional separator.
- [#492] Valentina crashes when add an increment.
- [#493] Error in seam allowance drawing.
# Version 0.4.4 April 12, 2016
- Updated measurement templates with all measurements. Added new template Aldrich/Women measurements.

View file

@ -1,4 +1,4 @@
valentina (0.4.3) trusty; urgency=low
valentina (0.4.4) trusty; urgency=low
* Auto build.

View file

@ -1,4 +1,4 @@
valentina (0.4.3) trusty; urgency=low
valentina (0.4.4) trusty; urgency=low
* Auto build.

2
dist/rpm/_service vendored
View file

@ -1,7 +1,7 @@
<services>
<service name="tar_scm">
<param name="url">https://github.com/dismine/Valentina.git</param>
<param name="versionprefix">0.4.3</param>
<param name="versionprefix">0.4.4</param>
<param name="filename">valentina</param>
<param name="scm">git</param>
<param name="versionformat">%at</param>

View file

@ -45,7 +45,7 @@ BuildRequires: libqt5-qtxmlpatterns-devel
Requires: poppler-utils
Version: 0.4.3
Version: 0.4.4
Release: 0
URL: https://bitbucket.org/dismine/valentina
License: GPL-3.0+
@ -161,6 +161,6 @@ rm -f dist/debian/%{name}.1.gz dist/debian/tape.1.gz dist/debian/%{name}.xml dis
%changelog
* Fri Nov 27 2015 Roman Telezhinskyi
* Fri Nov 27 2015 Roman Telezhynskyi
- Auto build

View file

@ -11,11 +11,9 @@ import argparse
import bisect
import getopt
import os
import pty
import re
import subprocess
import sys
import termios
symbolizers = {}
DEBUG = False
@ -25,6 +23,7 @@ sysroot_path = None
binary_name_filter = None
fix_filename_patterns = None
logfile = sys.stdin
allow_system_symbolizer = True
# FIXME: merge the code that calls fix_filename().
def fix_filename(file_name):
@ -78,7 +77,7 @@ class LLVMSymbolizer(Symbolizer):
cmd = [self.symbolizer_path,
'--use-symbol-table=true',
'--demangle=%s' % demangle,
'--functions=short',
'--functions=linkage',
'--inlining=true',
'--default-arch=%s' % self.default_arch]
if self.system == 'Darwin':
@ -136,12 +135,13 @@ class Addr2LineSymbolizer(Symbolizer):
super(Addr2LineSymbolizer, self).__init__()
self.binary = binary
self.pipe = self.open_addr2line()
self.output_terminator = -1
def open_addr2line(self):
addr2line_tool = 'addr2line'
if binutils_prefix:
addr2line_tool = binutils_prefix + addr2line_tool
cmd = [addr2line_tool, '-f']
cmd = [addr2line_tool, '-fi']
if demangle:
cmd += ['--demangle']
cmd += ['-e', self.binary]
@ -154,16 +154,23 @@ class Addr2LineSymbolizer(Symbolizer):
"""Overrides Symbolizer.symbolize."""
if self.binary != binary:
return None
lines = []
try:
print >> self.pipe.stdin, offset
function_name = self.pipe.stdout.readline().rstrip()
file_name = self.pipe.stdout.readline().rstrip()
print >> self.pipe.stdin, self.output_terminator
is_first_frame = True
while True:
function_name = self.pipe.stdout.readline().rstrip()
file_name = self.pipe.stdout.readline().rstrip()
if is_first_frame:
is_first_frame = False
elif function_name in ['', '??']:
assert file_name == function_name
break
lines.append((function_name, file_name));
except Exception:
function_name = ''
file_name = ''
file_name = fix_filename(file_name)
return ['%s in %s %s' % (addr, function_name, file_name)]
lines.append(('??', '??:0'))
return ['%s in %s %s' % (addr, function, fix_filename(file)) for (function, file) in lines]
class UnbufferedLineConverter(object):
"""
@ -171,6 +178,9 @@ class UnbufferedLineConverter(object):
output. Uses pty to trick the child into providing unbuffered output.
"""
def __init__(self, args, close_stderr=False):
# Local imports so that the script can start on Windows.
import pty
import termios
pid, fd = pty.fork()
if pid == 0:
# We're the child. Transfer control to command.
@ -261,7 +271,7 @@ def BreakpadSymbolizerFactory(binary):
def SystemSymbolizerFactory(system, addr, binary):
if system == 'Darwin':
return DarwinSymbolizer(addr, binary)
elif system == 'Linux':
elif system == 'Linux' or system == 'FreeBSD':
return Addr2LineSymbolizer(binary)
@ -341,17 +351,23 @@ class BreakpadSymbolizer(Symbolizer):
class SymbolizationLoop(object):
def __init__(self, binary_name_filter=None, dsym_hint_producer=None):
# Used by clients who may want to supply a different binary name.
# E.g. in Chrome several binaries may share a single .dSYM.
self.binary_name_filter = binary_name_filter
self.dsym_hint_producer = dsym_hint_producer
self.system = os.uname()[0]
if self.system not in ['Linux', 'Darwin', 'FreeBSD']:
raise Exception('Unknown system')
self.llvm_symbolizers = {}
self.last_llvm_symbolizer = None
self.dsym_hints = set([])
self.frame_no = 0
if sys.platform == 'win32':
# ASan on Windows uses dbghelp.dll to symbolize in-process, which works
# even in sandboxed processes. Nothing needs to be done here.
self.process_line = self.process_line_echo
else:
# Used by clients who may want to supply a different binary name.
# E.g. in Chrome several binaries may share a single .dSYM.
self.binary_name_filter = binary_name_filter
self.dsym_hint_producer = dsym_hint_producer
self.system = os.uname()[0]
if self.system not in ['Linux', 'Darwin', 'FreeBSD']:
raise Exception('Unknown system')
self.llvm_symbolizers = {}
self.last_llvm_symbolizer = None
self.dsym_hints = set([])
self.frame_no = 0
self.process_line = self.process_line_posix
def symbolize_address(self, addr, binary, offset):
# On non-Darwin (i.e. on platforms without .dSYM debug info) always use
@ -385,6 +401,8 @@ class SymbolizationLoop(object):
[BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]])
result = symbolizers[binary].symbolize(addr, binary, offset)
if result is None:
if not allow_system_symbolizer:
raise Exception('Failed to launch or use llvm-symbolizer.')
# Initialize system symbolizer only if other symbolizers failed.
symbolizers[binary].append_symbolizer(
SystemSymbolizerFactory(self.system, addr, binary))
@ -405,14 +423,14 @@ class SymbolizationLoop(object):
def process_logfile(self):
self.frame_no = 0
while True:
line = logfile.readline()
if not line:
break
for line in logfile:
processed = self.process_line(line)
print '\n'.join(processed)
def process_line(self, line):
def process_line_echo(self, line):
return [line.rstrip()]
def process_line_posix(self, line):
self.current_line = line.rstrip()
#0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45)
stack_trace_line_format = (
@ -437,20 +455,23 @@ class SymbolizationLoop(object):
if __name__ == '__main__':
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
description='ASan symbolization script',
epilog='''Example of use:
asan_symbolize.py -c "$HOME/opt/cross/bin/arm-linux-gnueabi-" -s "$HOME/SymbolFiles" < asan.log''')
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description='ASan symbolization script',
epilog='Example of use:\n'
'asan_symbolize.py -c "$HOME/opt/cross/bin/arm-linux-gnueabi-" '
'-s "$HOME/SymbolFiles" < asan.log')
parser.add_argument('path_to_cut', nargs='*',
help='pattern to be cut from the result file path ')
help='pattern to be cut from the result file path ')
parser.add_argument('-d','--demangle', action='store_true',
help='demangle function names')
help='demangle function names')
parser.add_argument('-s', metavar='SYSROOT',
help='set path to sysroot for sanitized binaries')
help='set path to sysroot for sanitized binaries')
parser.add_argument('-c', metavar='CROSS_COMPILE',
help='set prefix for binutils')
parser.add_argument('-l','--logfile', default=sys.stdin, type=argparse.FileType('r'),
help='set log file name to parse, default is stdin')
help='set prefix for binutils')
parser.add_argument('-l','--logfile', default=sys.stdin,
type=argparse.FileType('r'),
help='set log file name to parse, default is stdin')
args = parser.parse_args()
if args.path_to_cut:
fix_filename_patterns = args.path_to_cut

View file

@ -4,7 +4,7 @@
# Please, run this script from folder <root_folder>/scripts.
# usage:
# $ ./generate_tool_cursor.sh
# $ ./obs_debian.sh
# Note. For stable version enough create an archive debian.tar.gz with folder debian inside and download it.

View file

@ -0,0 +1,59 @@
<?xml version='1.0' encoding='UTF-8'?>
<pattern>
<!--Pattern created with Valentina (http://www.valentina-project.org/).-->
<version>0.3.1</version>
<unit>cm</unit>
<author/>
<description/>
<notes/>
<measurements/>
<increments>
<increment name="#Param1" description="" formula="0.2 "/>
<increment name="#Param2" description="" formula="3"/>
</increments>
<draw name="Test1">
<calculation>
<point type="single" x="0.79375" y="1.05833" id="1" name="A" mx="0.132292" my="0.264583"/>
<point type="endLine" typeLine="hair" id="2" name="A1" basePoint="1" mx="0.132292" lineColor="black" my="0.264583" angle="0" length="10"/>
<point type="normal" typeLine="hair" id="3" name="A2" firstPoint="2" secondPoint="1" mx="0.132292" lineColor="black" my="0.264583" angle="0" length="10"/>
<point type="alongLine" typeLine="none" id="4" name="A3" firstPoint="1" secondPoint="2" mx="0.132292" lineColor="black" my="0.264583" length="5"/>
<point type="normal" typeLine="none" id="5" name="A4" firstPoint="4" secondPoint="1" mx="0.132292" lineColor="black" my="0.264583" angle="0" length="4"/>
<spline type="simpleInteractive" point4="3" angle1="267.354" angle2="181.581" id="6" color="black" length1="5.48872" length2="8.92993" point1="1"/>
<point type="cutSpline" id="7" name="A5" spline="6" mx="-1.44194" my="-1.42325" length="Spl_A_A2*#Param1"/>
<point type="cutSpline" id="8" name="A6" spline="6" mx="-1.44193" my="-0.384582" length="Spl_A_A5+#Param2"/>
<line typeLine="hair" id="9" firstPoint="5" secondPoint="7" lineColor="black"/>
<line typeLine="hair" id="10" firstPoint="5" secondPoint="8" lineColor="black"/>
<point type="alongLine" typeLine="none" id="11" name="A7" firstPoint="2" secondPoint="3" mx="0.132292" lineColor="black" my="0.264583" length="5"/>
<line typeLine="hair" id="12" firstPoint="5" secondPoint="11" lineColor="black"/>
<operation type="rotation" suffix="a1" id="13" center="5" angle="323.758">
<source>
<item idObject="8"/>
<item idObject="6"/>
<item idObject="3"/>
<item idObject="11"/>
</source>
<destination>
<item idObject="14" mx="-2.75649" my="0.70277"/>
<item idObject="15" mx="5.68188e+07" my="5.68188e+07"/>
<item idObject="16" mx="0.132292" my="0.264583"/>
<item idObject="17" mx="0.132292" my="0.264583"/>
</destination>
</operation>
<line typeLine="hair" id="18" firstPoint="5" secondPoint="17" lineColor="black"/>
<line typeLine="hair" id="19" firstPoint="17" secondPoint="16" lineColor="black"/>
</calculation>
<modeling>
<point type="modeling" inUse="true" id="20" idObject="16" mx="0.132292" my="0.264583"/>
<spline type="modelingSpline" inUse="true" id="21" idObject="15"/>
<point type="modeling" inUse="true" id="22" idObject="14" mx="-2.75649" my="0.70277"/>
</modeling>
<details>
<detail closed="1" id="23" name="Деталь" supplement="1" mx="0" width="1" my="0">
<node type="NodePoint" nodeType="Contour" idObject="20" mx="0" my="0"/>
<node type="NodeSpline" reverse="1" nodeType="Contour" idObject="21" mx="0" my="0"/>
<node type="NodePoint" nodeType="Contour" idObject="22" mx="0" my="0"/>
</detail>
</details>
<groups/>
</draw>
</pattern>

View file

@ -0,0 +1,100 @@
<?xml version='1.0' encoding='UTF-8'?>
<pattern>
<!--Pattern created with Valentina (http://www.valentina-project.org/).-->
<version>0.2.4</version>
<unit>mm</unit>
<author/>
<description/>
<notes/>
<measurements>Issue_#493.vit</measurements>
<increments>
<increment name="#Прибавка_1" description="П рибавка на свободное облега н и е по л и н и и груди 0,6 см, для&#xa;пол н ы х фи гур - \ ,3 см." formula="12"/>
</increments>
<draw name="Юбка">
<calculation>
<point type="single" x="7.9375" y="494.2" id="153" name="A2" mx="1.32292" my="2.64583"/>
<point type="endLine" typeLine="hair" id="154" name="B2" basePoint="153" mx="1.32292" lineColor="black" angle="270" my="2.64583" length="@Длинабки"/>
<point type="endLine" typeLine="hair" id="155" name="C2" basePoint="153" mx="-12.7033" lineColor="black" angle="270" my="1.44359" length="@М_25_f"/>
<point type="endLine" typeLine="hair" id="156" name="D2" basePoint="153" mx="-7.47813" lineColor="black" angle="180" my="-14.9562" length="@М_23_b+@P_3"/>
<point type="endLine" typeLine="hair" id="157" name="E2" basePoint="155" mx="1.32292" lineColor="black" angle="180" my="2.64583" length="Line_A2_D2"/>
<point type="endLine" typeLine="hair" id="158" name="F2" basePoint="154" mx="1.32292" lineColor="black" angle="180" my="2.64583" length="Line_A2_D2"/>
<line typeLine="hair" id="159" firstPoint="156" secondPoint="158" lineColor="black"/>
<point type="endLine" typeLine="hair" id="160" name="H2" basePoint="153" mx="-1.08157" lineColor="black" angle="0" my="-13.7848" length="@М_23_f+@P_3"/>
<point type="endLine" typeLine="hair" id="161" name="I2" basePoint="155" mx="1.32292" lineColor="black" angle="0" my="2.64583" length="Line_A2_H2"/>
<point type="endLine" typeLine="hair" id="162" name="J2" basePoint="154" mx="1.32292" lineColor="black" angle="0" my="2.64583" length="Line_A2_H2"/>
<line typeLine="hair" id="163" firstPoint="162" secondPoint="160" lineColor="black"/>
<point type="endLine" typeLine="hair" id="164" name="K2" basePoint="156" mx="-18.2007" lineColor="black" angle="0" my="5.76961" length="@М_19_b+@P_4+@V_4*2"/>
<point type="endLine" typeLine="hair" id="165" name="L2" basePoint="156" mx="-17.9251" lineColor="black" angle="0" my="-12.258" length="@М_20_b"/>
<point type="endLine" typeLine="hair" id="166" name="L22" basePoint="165" mx="-9.71167" lineColor="black" angle="0" my="-15.5309" length="@V_4/2"/>
<point type="endLine" typeLine="hair" id="167" name="L23" basePoint="166" mx="2.49639" lineColor="black" angle="0" my="-14.3494" length="@V_4/2"/>
<point type="endLine" typeLine="hair" id="168" name="L24" basePoint="167" mx="-9.61661" lineColor="black" angle="0" my="-14.5764" length="@V_5"/>
<point type="normal" typeLine="hair" id="169" name="K2_" firstPoint="164" secondPoint="156" mx="1.32292" lineColor="black" angle="0" my="2.64583" length="20"/>
<point type="normal" typeLine="hair" id="170" name="K2__" firstPoint="164" secondPoint="153" mx="-4.94107" lineColor="black" angle="0" my="-13.7622" length="20"/>
<point type="endLine" typeLine="hair" id="171" name="M2" basePoint="160" mx="6.00859" lineColor="black" angle="180" my="6.55055" length="@М_19_f+@P_4+@V_3*2"/>
<point type="endLine" typeLine="hair" id="172" name="N2" basePoint="160" mx="3.08313" lineColor="blue" angle="180" my="3.23257" length="@М_20_f"/>
<point type="endLine" typeLine="hair" id="173" name="N22" basePoint="172" mx="-5.90801" lineColor="black" angle="180" my="-18.4356" length="@V_3/2"/>
<point type="endLine" typeLine="hair" id="174" name="N23" basePoint="173" mx="-17.4526" lineColor="black" angle="180" my="2.0591" length="@V_3/2"/>
<point type="endLine" typeLine="hair" id="175" name="N24" basePoint="174" mx="2.3104" lineColor="blue" angle="180" my="-16.6754" length="@V_5"/>
<point type="normal" typeLine="hair" id="176" name="M2_" firstPoint="171" secondPoint="153" mx="-3.36275" lineColor="black" angle="0" my="6.55055" length="20"/>
<point type="normal" typeLine="hair" id="177" name="M2__" firstPoint="171" secondPoint="153" mx="-7.86649" lineColor="black" angle="180" my="-15.3077" length="20"/>
<point type="endLine" typeLine="hair" id="178" name="Q2" basePoint="171" mx="7.19027" lineColor="black" angle="90" my="-13.7828" length="@P_5"/>
<point type="endLine" typeLine="hair" id="179" name="P2" basePoint="164" mx="-15.1057" lineColor="black" angle="90" my="-12.6093" length="@P_5"/>
<point type="endLine" typeLine="hair" id="180" name="G2" basePoint="156" mx="-16.2791" lineColor="black" angle="270" my="-3.80826" length="@P_5"/>
<point type="endLine" typeLine="hair" id="181" name="L25" basePoint="168" mx="-8.11194" lineColor="black" angle="0" my="4.81139" length="@V_4/2"/>
<point type="endLine" typeLine="hair" id="182" name="L26" basePoint="181" mx="3.3101" lineColor="black" angle="0" my="-13.5828" length="@V_4/2"/>
<point type="endLine" typeLine="dotLine" id="183" name="L27" basePoint="166" mx="-20.27" lineColor="black" angle="270" my="0.795005" length="@V_7"/>
<point type="endLine" typeLine="dotLine" id="184" name="L28" basePoint="181" mx="1.32292" lineColor="black" angle="270" my="2.64583" length="@V_7"/>
<point type="endLine" typeLine="hair" id="185" name="N25" basePoint="175" mx="-14.519" lineColor="black" angle="180" my="-19.0634" length="@V_3/2"/>
<point type="endLine" typeLine="hair" id="186" name="N26" basePoint="185" mx="-25.0802" lineColor="black" angle="180" my="3.23257" length="@V_3/2"/>
<point type="endLine" typeLine="dotLine" id="187" name="N27" basePoint="185" mx="1.32292" lineColor="black" angle="270" my="2.64583" length="@V_6"/>
<point type="endLine" typeLine="dotLine" id="188" name="N28" basePoint="173" mx="1.32292" lineColor="black" angle="270" my="2.64583" length="@V_6"/>
<line typeLine="hair" id="189" firstPoint="165" secondPoint="183" lineColor="black"/>
<line typeLine="hair" id="190" firstPoint="167" secondPoint="183" lineColor="black"/>
<line typeLine="hair" id="191" firstPoint="168" secondPoint="184" lineColor="blue"/>
<line typeLine="hair" id="192" firstPoint="182" secondPoint="184" lineColor="blue"/>
<line typeLine="hair" id="193" firstPoint="186" secondPoint="187" lineColor="blue"/>
<line typeLine="hair" id="194" firstPoint="175" secondPoint="187" lineColor="blue"/>
<line typeLine="hair" id="195" firstPoint="174" secondPoint="188" lineColor="blue"/>
<line typeLine="hair" id="196" firstPoint="188" secondPoint="172" lineColor="blue"/>
<spline point4="186" type="simple" kAsm1="1.23136" kAsm2="1.01111" angle1="351.775" angle2="179.264" id="197" kCurve="1" color="blue" point1="178"/>
<point type="pointOfContact" id="198" name="C2_" radius="@М_26" center="179" firstPoint="153" secondPoint="155" mx="3.72744" my="-9.37662"/>
<spline point4="198" type="simple" kAsm1="0.855702" kAsm2="1.0005" angle1="279.038" angle2="92.5636" id="199" kCurve="1" color="blue" point1="179"/>
<spline point4="178" type="simple" kAsm1="0.974179" kAsm2="0.819183" angle1="86.9349" angle2="257.215" id="200" kCurve="1" color="blue" point1="198"/>
<spline point4="179" type="simple" kAsm1="1.13769" kAsm2="0.265028" angle1="359.194" angle2="194.757" id="201" kCurve="1" color="black" point1="180"/>
<point type="curveIntersectAxis" typeLine="hair" id="202" name="L29" curve="201" basePoint="165" mx="-19.6531" lineColor="black" angle="275.993" my="3.67407"/>
<point type="curveIntersectAxis" typeLine="hair" id="203" name="L21" curve="201" basePoint="167" mx="-16.3627" lineColor="black" angle="263.976" my="1.2063"/>
<arc type="simple" angle1="270" angle2="290" id="204" radius="Line_L2_L27" center="202" color="black"/>
<arc type="simple" angle1="260" angle2="280" id="205" radius="Line_L2_L27" center="203" color="black"/>
<point type="pointOfIntersectionArcs" crossPoint="1" firstArc="204" id="206" name="S2" secondArc="205" mx="1.32292" my="2.64583"/>
<line typeLine="hair" id="207" firstPoint="202" secondPoint="206" lineColor="blue"/>
<line typeLine="hair" id="208" firstPoint="206" secondPoint="203" lineColor="blue"/>
<point type="curveIntersectAxis" typeLine="hair" id="209" name="R2" curve="201" basePoint="168" mx="-16.9797" lineColor="black" angle="275.774" my="4.70231"/>
<point type="curveIntersectAxis" typeLine="hair" id="210" name="T2" curve="201" basePoint="182" mx="5.64151" lineColor="black" angle="264.116" my="2.85148"/>
<spline point4="202" type="simple" kAsm1="1" kAsm2="1" angle1="0" angle2="180" id="211" kCurve="1" color="blue" point1="180"/>
<spline point4="209" type="simple" kAsm1="1" kAsm2="1" angle1="2" angle2="182" id="212" kCurve="1" color="blue" point1="203"/>
<spline point4="179" type="simple" kAsm1="1.03156" kAsm2="0.960515" angle1="2.61019" angle2="190.587" id="213" kCurve="1" color="blue" point1="210"/>
</calculation>
<modeling>
<point type="modeling" inUse="true" id="257" idObject="178" mx="7.19027" my="-13.7828"/>
<spline type="modelingSpline" inUse="true" id="258" idObject="197"/>
<point type="modeling" inUse="true" id="262" idObject="174" mx="-17.4526" my="2.0591"/>
<point type="modeling" inUse="true" id="263" idObject="188" mx="1.32292" my="2.64583"/>
<point type="modeling" inUse="true" id="264" idObject="172" mx="3.08313" my="3.23257"/>
<point type="modeling" inUse="true" id="265" idObject="160" mx="-1.08157" my="-13.7848"/>
<point type="modeling" inUse="true" id="266" idObject="161" mx="1.32292" my="2.64583"/>
<point type="modeling" inUse="true" id="267" idObject="155" mx="-12.7033" my="1.44359"/>
</modeling>
<details>
<detail closed="1" id="268" name="Деталь" supplement="1" mx="-35.0407" width="12" my="103.099">
<node type="NodePoint" nodeType="Contour" idObject="257" mx="0" my="0"/>
<node type="NodeSpline" reverse="0" nodeType="Contour" idObject="258" mx="0" my="0"/>
<node type="NodePoint" nodeType="Contour" idObject="262" mx="0" my="0"/>
<node type="NodePoint" nodeType="Contour" idObject="263" mx="0" my="0"/>
<node type="NodePoint" nodeType="Contour" idObject="264" mx="0" my="0"/>
<node type="NodePoint" nodeType="Contour" idObject="265" mx="0" my="0"/>
<node type="NodePoint" nodeType="Contour" idObject="266" mx="0" my="0"/>
<node type="NodePoint" nodeType="Contour" idObject="267" mx="0" my="0"/>
</detail>
</details>
</draw>
</pattern>

View file

@ -0,0 +1,73 @@
<?xml version='1.0' encoding='UTF-8'?>
<vit>
<!--Measurements created with Valentina (http://www.valentina-project.org/).-->
<version>0.3.3</version>
<read-only>false</read-only>
<notes/>
<unit>mm</unit>
<pm_system>998</pm_system>
<personal>
<family-name/>
<given-name/>
<birth-date>1800-01-01</birth-date>
<gender>female</gender>
<email/>
</personal>
<body-measurements>
<m full_name="Обхват груди" value="92" name="@М_1"/>
<m full_name="Обхват талии" value="70" name="@М_2"/>
<m full_name="Обхват бедер на уровне выпуклости живота" value="87" name="@М_3"/>
<m full_name="Обхват бедер" value="96" name="@М_4"/>
<m full_name="Длина_посерединеоалии (Перед)" value="371" name="@М_5_f"/>
<m full_name="Длина_посерединеоалии (Спина)" value="425" name="@М_5_b"/>
<m full_name="Длинаоалии (перед)" value="448 " name="@М_6_f"/>
<m full_name="Длинаоалии (спина)" value="444" name="@М_6_b"/>
<m full_name="Высота плеча косая " value="450" name="@М_7_f"/>
<m full_name="Высота плеча косая " value="431" name="@М_7_b"/>
<m full_name="Длина от точк и основания шеи до талии" value="451" name="@М_8"/>
<m full_name="Высота груди" value="241" name="@М_9"/>
<m full_name="Радиус грудной железы" value="76" description="Радиус грудной железы B- 76" name="@М_9_R"/>
<m full_name="Расстояние между точками центра груди" value="98" name="@М_10"/>
<m full_name="Длина боковой линии до талии" value="213" name="@М_11"/>
<m full_name="Ширина шеи сзади" value="76" name="@М_12"/>
<m full_name="Ширина плечевого ската" value="134" name="@М_13"/>
<m full_name="Ширина плеча" value="197" name="@М_14_f"/>
<m full_name="Ширина плеча" value="203" name="@М_14_b"/>
<m full_name="Ширина груди" value="171" name="@М_15"/>
<m full_name="Ширина спины" value="177" name="@М_16"/>
<m full_name="Ширина груди с учетом выпуклости грудных желез" value="254" name="@М_17"/>
<m full_name="Ширина спины на уровне глубины проймы" value="219" name="@М_18"/>
<m full_name="Ширина талии" value="178" name="@М_19_f"/>
<m full_name="Ширина талии" value="169" name="@М_19_b"/>
<m full_name="Месторасположение вытачки " value="83" name="@М_20_f"/>
<m full_name="Месторасположение вытачки " value="83" name="@М_20_b"/>
<m full_name="номер не используется" value="0" name="@М_21"/>
<m full_name="Ширина бедер на уровне выпуклости живота" value="209" name="@М_22_f"/>
<m full_name="Ширина бедер на уровне выпуклости живота" value="216" name="@М_22_b"/>
<m full_name="Ширина бедер" value="232" name="@М_23_f"/>
<m full_name="Ширина бедер" value="245" name="@М_23_b"/>
<m full_name="Высота сидения" value="254" name="@М_24"/>
<m full_name="Высота бедер:&#xa;По средней линии переда" value="203" name="@М_25_f"/>
<m full_name="Высота бедер:&#xa;По средней линии спины" value="200" name="@М_25_b"/>
<m full_name="Высота бедер сбоку" value="206" name="@М_26"/>
<m full_name="Длина сбоку от линии талии до колена" value="584" name="@М_27"/>
<m full_name="Дуга через паховую область" value="660" name="@М_28"/>
<m full_name="Обхват верхней части бедра" value="546" name="@М_29"/>
<m full_name="Обхват колена" value="356" name="@М_30"/>
<m full_name="Обхват и кры" value="330" name="@М_31"/>
<m full_name="Обхват щи колотки" value="228" name="@М_32"/>
<m full_name="Прибавка на свободное облегание по линии груди " value="6" description="Прибавка на свободное облегание по линии груди 0,6 см, для полных фигур - 1 ,3 см.&#xa;Можно сделать как функцию от полноты - ширины груди&#xa;Используется и на спине по линии талии... Может надо разделить" name="@P_1"/>
<m full_name="Прибавка (спины) на свободное облегание по линии проймы" value="19" name="@P_2"/>
<m full_name="Прибавка (в юбке )на свободное облегание по линии бедер" value="13" name="@P_3"/>
<m full_name="Прибавка (в юбке )на свободное облегание по линии талии" value="6" name="@P_4"/>
<m full_name="Неровность линии талии на юбке" value="5" description="превышение боковых точкек и занижение передней точки" name="@P_5"/>
<m full_name="Раствор вытачки по талии на спине" value="38" description="Раствор вытачки по талии на спине - 38 , для дестких размеров 25" name="@V_1"/>
<m full_name="Раствор вытачки плечевой" value="12" description="Раствор вытачки плечевой - видимо на выпуклость лопатки -12" name="@V_2"/>
<m full_name="Раствор одной вытачки (из двух) переда юбки (ПП) по талии " value="16" name="@V_3"/>
<m full_name="Раствор одной вытачки (из двух) зада юбки (ЗП) по талии " value="29" name="@V_4"/>
<m full_name="Расстояние между парой вытачек" value="32" name="@V_5"/>
<m full_name="Длина вытачки переда юбки (ПП) по талии" value="90" name="@V_6"/>
<m full_name="Длина вытачки зада юбки (ЗП) по талии" value="140" name="@V_7"/>
<m full_name="Длина юбки" value="@М_27" description="Длина юбки - наприимер до колена" name="@Длинабки"/>
</body-measurements>
</vit>

View file

@ -41,7 +41,7 @@ class DialogAboutTape : public QDialog
public:
explicit DialogAboutTape(QWidget *parent = 0);
~DialogAboutTape();
virtual ~DialogAboutTape();
protected:
virtual void changeEvent(QEvent* event) Q_DECL_OVERRIDE;

View file

@ -0,0 +1,168 @@
/************************************************************************
**
** @file dialogexporttocsv.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 1 6, 2016
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2016 Valentina project
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "dialogexporttocsv.h"
#include "ui_dialogexporttocsv.h"
#include "../vmisc/vtapesettings.h"
#include "../mapplication.h"
#include <QPushButton>
#include <QShowEvent>
#include <QTextCodec>
//---------------------------------------------------------------------------------------------------------------------
DialogExportToCSV::DialogExportToCSV(QWidget *parent)
: QDialog(parent),
ui(new Ui::DialogExportToCSV),
isInitialized(false)
{
ui->setupUi(this);
ui->checkBoxWithHeader->setChecked(qApp->TapeSettings()->GetCSVWithHeader());
foreach (int mib, QTextCodec::availableMibs())
{
ui->comboBoxCodec->addItem(QTextCodec::codecForMib(mib)->name(), mib);
}
ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(qApp->TapeSettings()->GetCSVCodec()));
SetSeparator(qApp->TapeSettings()->GetCSVSeparator());
QPushButton *bDefaults = ui->buttonBox->button(QDialogButtonBox::RestoreDefaults);
SCASSERT(bDefaults != nullptr);
connect(bDefaults, &QPushButton::clicked, this, &DialogExportToCSV::RestoreDefaults);
}
//---------------------------------------------------------------------------------------------------------------------
DialogExportToCSV::~DialogExportToCSV()
{
delete ui;
}
//---------------------------------------------------------------------------------------------------------------------
bool DialogExportToCSV::WithHeader() const
{
return ui->checkBoxWithHeader->isChecked();
}
//---------------------------------------------------------------------------------------------------------------------
int DialogExportToCSV::SelectedMib() const
{
#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
return ui->comboBoxCodec->itemData(ui->comboBoxCodec->currentIndex()).toInt();
#else
return ui->comboBoxCodec->currentData().toInt();
#endif
}
//---------------------------------------------------------------------------------------------------------------------
QChar DialogExportToCSV::Separator() const
{
if (ui->radioButtonTab->isChecked())
{
return QChar('\t');
}
else if (ui->radioButtonSemicolon->isChecked())
{
return QChar(';');
}
else if (ui->radioButtonSpace->isChecked())
{
return QChar(' ');
}
else
{
return QChar(',');
}
}
//---------------------------------------------------------------------------------------------------------------------
void DialogExportToCSV::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange)
{
// retranslate designer form (single inheritance approach)
ui->retranslateUi(this);
}
// remember to call base class implementation
QDialog::changeEvent(event);
}
//---------------------------------------------------------------------------------------------------------------------
void DialogExportToCSV::showEvent(QShowEvent *event)
{
QDialog::showEvent( event );
if ( event->spontaneous() )
{
return;
}
if (isInitialized)
{
return;
}
// do your init stuff here
setMaximumSize(size());
setMinimumSize(size());
isInitialized = true;//first show windows are held
}
//---------------------------------------------------------------------------------------------------------------------
void DialogExportToCSV::RestoreDefaults()
{
ui->checkBoxWithHeader->setChecked(qApp->TapeSettings()->GetDefCSVWithHeader());
ui->comboBoxCodec->setCurrentIndex(ui->comboBoxCodec->findData(qApp->TapeSettings()->GetDefCSVCodec()));
SetSeparator(qApp->TapeSettings()->GetDefCSVSeparator());
}
//---------------------------------------------------------------------------------------------------------------------
void DialogExportToCSV::SetSeparator(const QChar &separator)
{
switch(separator.toLatin1())
{
case '\t':
ui->radioButtonTab->setChecked(true);
break;
case ';':
ui->radioButtonSemicolon->setChecked(true);
break;
case ' ':
ui->radioButtonSpace->setChecked(true);
break;
case ',':
default:
ui->radioButtonComma->setChecked(true);
break;
}
}

View file

@ -0,0 +1,65 @@
/************************************************************************
**
** @file dialogexporttocsv.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 1 6, 2016
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2016 Valentina project
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef DIALOGEXPORTTOCSV_H
#define DIALOGEXPORTTOCSV_H
#include <QDialog>
namespace Ui {
class DialogExportToCSV;
}
class DialogExportToCSV : public QDialog
{
Q_OBJECT
public:
explicit DialogExportToCSV(QWidget *parent = nullptr);
virtual ~DialogExportToCSV();
bool WithHeader() const;
int SelectedMib() const;
QChar Separator() const;
protected:
virtual void changeEvent(QEvent* event) Q_DECL_OVERRIDE;
virtual void showEvent(QShowEvent *event) Q_DECL_OVERRIDE;
private slots:
void RestoreDefaults();
private:
Q_DISABLE_COPY(DialogExportToCSV)
Ui::DialogExportToCSV *ui;
bool isInitialized;
void SetSeparator(const QChar &separator);
};
#endif // DIALOGEXPORTTOCSV_H

View file

@ -0,0 +1,167 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DialogExportToCSV</class>
<widget class="QDialog" name="DialogExportToCSV">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>333</width>
<height>292</height>
</rect>
</property>
<property name="windowTitle">
<string>Export options</string>
</property>
<property name="windowIcon">
<iconset resource="../share/resources/tapeicon.qrc">
<normaloff>:/tapeicon/64x64/logo.png</normaloff>:/tapeicon/64x64/logo.png</iconset>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QGroupBox" name="groupBoxExport">
<property name="title">
<string>Export</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="checkBoxWithHeader">
<property name="text">
<string>With header</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Codec:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBoxCodec"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxSeparator">
<property name="title">
<string>Separator</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QRadioButton" name="radioButtonTab">
<property name="text">
<string>Tab</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonComma">
<property name="text">
<string>Comma</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonSemicolon">
<property name="text">
<string>Semicolon</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonSpace">
<property name="text">
<string>Space</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../share/resources/tapeicon.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>DialogExportToCSV</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>DialogExportToCSV</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
<buttongroups>
<buttongroup name="buttonGroup"/>
</buttongroups>
</ui>

View file

@ -84,6 +84,14 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
type = QtWarningMsg;
}
#if !defined(V_NO_DEBUG)
// I have decided to hide this annoing message for release builds.
if ((type == QtWarningMsg) && msg.contains("setGeometryDp: Unable to set geometry"))
{
type = QtDebugMsg;
}
#endif //!defined(V_NO_DEBUG)
#if defined(Q_OS_MAC)
# if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) && QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
// Try hide very annoying, Qt related, warnings in Mac OS X
@ -410,7 +418,7 @@ void MApplication::InitTrVars()
}
else
{
trVars = new VTranslateVars(TapeSettings()->GetOsSeparator());
trVars = new VTranslateVars();
}
}

View file

@ -11,6 +11,7 @@ SOURCES += \
$$PWD/dialogs/tapeconfigdialog.cpp \
$$PWD/dialogs/configpages/tapeconfigurationpage.cpp \
$$PWD/dialogs/configpages/tapepathpage.cpp \
$$PWD/dialogs/dialogexporttocsv.cpp \
$$PWD/vlitepattern.cpp \
$$PWD/vtablesearch.cpp
@ -27,6 +28,7 @@ HEADERS += \
$$PWD/dialogs/tapeconfigdialog.h \
$$PWD/dialogs/configpages/tapeconfigurationpage.h \
$$PWD/dialogs/configpages/tapepathpage.h \
$$PWD/dialogs/dialogexporttocsv.h \
$$PWD/vlitepattern.h \
$$PWD/vtablesearch.h
@ -34,4 +36,5 @@ FORMS += \
$$PWD/tmainwindow.ui \
$$PWD/dialogs/dialogabouttape.ui \
$$PWD/dialogs/dialognewmeasurements.ui \
$$PWD/dialogs/dialogmdatabase.ui
$$PWD/dialogs/dialogmdatabase.ui \
$$PWD/dialogs/dialogexporttocsv.ui

View file

@ -32,6 +32,7 @@
#include "dialogs/dialognewmeasurements.h"
#include "dialogs/dialogmdatabase.h"
#include "dialogs/tapeconfigdialog.h"
#include "dialogs/dialogexporttocsv.h"
#include "../vpatterndb/calculator.h"
#include "../ifc/ifcdef.h"
#include "../ifc/xml/vvitconverter.h"
@ -39,6 +40,7 @@
#include "../ifc/xml/vpatternconverter.h"
#include "../vmisc/vlockguard.h"
#include "../vmisc/vsysexits.h"
#include "../vmisc/qxtcsvmodel.h"
#include "vlitepattern.h"
#include "../qmuparser/qmudef.h"
#include "../vtools/dialogs/support/dialogeditwrongformula.h"
@ -50,6 +52,8 @@
#include <QMessageBox>
#include <QComboBox>
#include <QProcess>
#include <QtNumeric>
#include <QTextCodec>
#if defined(Q_OS_MAC)
#include <QMimeData>
@ -678,6 +682,80 @@ void TMainWindow::FileSaveAs()
}
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::ExportToCSV()
{
const QString filters = tr("Comma-Separated Values (*.cvs)");
const QString suffix("csv");
const QString path = QDir::homePath() + "/" + tr("measurements"); + "." + suffix;
QString fileName = QFileDialog::getSaveFileName(this, tr("Export to CSV"), path, filters);
if (fileName.isEmpty())
{
return;
}
QFileInfo f( fileName );
if (f.suffix().isEmpty() && f.suffix() != suffix)
{
fileName += "." + suffix;
}
DialogExportToCSV dialog(this);
if (dialog.exec() == QDialog::Accepted)
{
QxtCsvModel csv;
const int columns = ui->tableWidget->columnCount();
{
int colCount = 0;
for (int column = 0; column < columns; ++column)
{
if (not ui->tableWidget->isColumnHidden(column))
{
csv.insertColumn(colCount++);
}
}
}
if (dialog.WithHeader())
{
int colCount = 0;
for (int column = 0; column < columns; ++column)
{
if (not ui->tableWidget->isColumnHidden(column))
{
QTableWidgetItem *header = ui->tableWidget->horizontalHeaderItem(colCount);
csv.setHeaderText(colCount, header->text());
++colCount;
}
}
}
const int rows = ui->tableWidget->rowCount();
for (int row = 0; row < rows; ++row)
{
csv.insertRow(row);
int colCount = 0;
for (int column = 0; column < columns; ++column)
{
if (not ui->tableWidget->isColumnHidden(column))
{
QTableWidgetItem *item = ui->tableWidget->item(row, column);
csv.setText(row, colCount, item->text());
++colCount;
}
}
}
csv.toCSV(fileName, dialog.WithHeader(), dialog.Separator(), QTextCodec::codecForMib(dialog.SelectedMib()));
qApp->TapeSettings()->SetCSVSeparator(dialog.Separator());
qApp->TapeSettings()->SetCSVCodec(dialog.SelectedMib());
qApp->TapeSettings()->SetCSVWithHeader(dialog.WithHeader());
}
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::AboutToShowWindowMenu()
{
@ -862,6 +940,8 @@ void TMainWindow::Remove()
{
MFields(false);
ui->actionExportToCSV->setEnabled(false);
ui->lineEditName->blockSignals(true);
ui->lineEditName->setText("");
ui->lineEditName->blockSignals(false);
@ -1012,6 +1092,9 @@ void TMainWindow::Fx()
if (dialog->exec() == QDialog::Accepted)
{
// Fix the bug #492. https://bitbucket.org/dismine/valentina/issues/492/valentina-crashes-when-add-an-increment
// Because of the bug need to take QTableWidgetItem twice time. Previous update "killed" the pointer.
const QTableWidgetItem *nameField = ui->tableWidget->item(row, ColumnName);
m->SetMValue(nameField->data(Qt::UserRole).toString(), dialog->GetFormula());
MeasurementsWasSaved(false);
@ -1056,13 +1139,15 @@ void TMainWindow::AddCustom()
ui->tableWidget->selectRow(currentRow);
ui->actionExportToCSV->setEnabled(true);
MeasurementsWasSaved(false);
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::AddKnown()
{
DialogMDataBase *dialog = new DialogMDataBase(m->ListKnown(), this);
QScopedPointer<DialogMDataBase> dialog (new DialogMDataBase(m->ListKnown(), this));
if (dialog->exec() == QDialog::Accepted)
{
qint32 currentRow;
@ -1110,9 +1195,10 @@ void TMainWindow::AddKnown()
ui->tableWidget->selectRow(currentRow);
ui->actionExportToCSV->setEnabled(true);
MeasurementsWasSaved(false);
}
delete dialog;
}
//---------------------------------------------------------------------------------------------------------------------
@ -1292,7 +1378,7 @@ void TMainWindow::ShowMData()
QString formula;
try
{
formula = qApp->TrVars()->FormulaToUser(meash->GetFormula());
formula = qApp->TrVars()->FormulaToUser(meash->GetFormula(), qApp->Settings()->GetOsSeparator());
}
catch (qmu::QmuParserError &e)
{
@ -1478,7 +1564,7 @@ void TMainWindow::SaveMValue()
try
{
const QString formula = qApp->TrVars()->FormulaFromUser(text, true);
const QString formula = qApp->TrVars()->FormulaFromUser(text, qApp->Settings()->GetOsSeparator());
m->SetMValue(nameField->data(Qt::UserRole).toString(), formula);
}
catch (qmu::QmuParserError &e) // Just in case something bad will happen
@ -1728,6 +1814,7 @@ void TMainWindow::SetupMenu()
connect(ui->actionSaveAs, &QAction::triggered, this, &TMainWindow::FileSaveAs);
ui->actionSaveAs->setShortcuts(QKeySequence::SaveAs);
connect(ui->actionExportToCSV, &QAction::triggered, this, &TMainWindow::ExportToCSV);
connect(ui->actionReadOnly, &QAction::triggered, this, &TMainWindow::ReadOnly);
connect(ui->actionPreferences, &QAction::triggered, this, &TMainWindow::Preferences);
@ -2254,7 +2341,7 @@ void TMainWindow::RefreshTable()
QString formula;
try
{
formula = qApp->TrVars()->FormulaToUser(meash->GetFormula());
formula = qApp->TrVars()->FormulaToUser(meash->GetFormula(), qApp->Settings()->GetOsSeparator());
}
catch (qmu::QmuParserError &e)
{
@ -2298,6 +2385,11 @@ void TMainWindow::RefreshTable()
ui->tableWidget->resizeRowsToContents();
ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
ui->tableWidget->blockSignals(false);
if (ui->tableWidget->rowCount() > 0)
{
ui->actionExportToCSV->setEnabled(true);
}
}
//---------------------------------------------------------------------------------------------------------------------
@ -2410,16 +2502,24 @@ bool TMainWindow::EvalFormula(const QString &formula, bool fromUser, VContainer
QString f;
if (fromUser)
{
f = qApp->TrVars()->FormulaFromUser(formula, true);
f = qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
}
else
{
f = formula;
}
f.replace("\n", " ");
Calculator *cal = new Calculator();
const qreal result = UnitConvertor(cal->EvalFormula(data->PlainVariables(), f), mUnit, pUnit);
delete cal;
QScopedPointer<Calculator> cal(new Calculator());
qreal result = cal->EvalFormula(data->PlainVariables(), f);
if (qIsInf(result) || qIsNaN(result))
{
label->setText(tr("Error") + " (" + postfix + ").");
label->setToolTip(tr("Invalid value"));
return false;
}
result = UnitConvertor(result, mUnit, pUnit);
label->setText(qApp->LocaleToString(result) + " " +postfix);
label->setToolTip(tr("Value"));

View file

@ -79,6 +79,7 @@ protected:
private slots:
void FileSave();
void FileSaveAs();
void ExportToCSV();
void AboutToShowWindowMenu();
void ShowWindow();
void AboutApplication();

View file

@ -913,6 +913,7 @@
<addaction name="separator"/>
<addaction name="actionSave"/>
<addaction name="actionSaveAs"/>
<addaction name="actionExportToCSV"/>
<addaction name="separator"/>
<addaction name="actionReadOnly"/>
<addaction name="separator"/>
@ -1249,6 +1250,17 @@
<enum>QAction::NoRole</enum>
</property>
</action>
<action name="actionExportToCSV">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Export to CSV</string>
</property>
<property name="menuRole">
<enum>QAction::NoRole</enum>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>

View file

@ -59,6 +59,12 @@ QString VLitePattern::GenerateLabel(const LabelType &type, const QString &reserv
return QString();
}
//---------------------------------------------------------------------------------------------------------------------
QString VLitePattern::GenerateSuffix() const
{
return QString();
}
//---------------------------------------------------------------------------------------------------------------------
void VLitePattern::UpdateToolData(const quint32 &id, VContainer *data)
{

View file

@ -43,6 +43,7 @@ public:
virtual void DecrementReferens(quint32 id) const Q_DECL_OVERRIDE;
virtual QString GenerateLabel(const LabelType &type, const QString &reservedName = QString())const Q_DECL_OVERRIDE;
virtual QString GenerateSuffix() const Q_DECL_OVERRIDE;
virtual void UpdateToolData(const quint32 &id, VContainer *data) Q_DECL_OVERRIDE;

View file

@ -80,6 +80,14 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
type = QtWarningMsg;
}
#if !defined(V_NO_DEBUG)
// I have decided to hide this annoing message for release builds.
if ((type == QtWarningMsg) && msg.contains("setGeometryDp: Unable to set geometry"))
{
type = QtDebugMsg;
}
#endif //!defined(V_NO_DEBUG)
#if defined(Q_OS_MAC)
# if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) && QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
// Try hide very annoying, Qt related, warnings in Mac OS X
@ -613,7 +621,7 @@ void VApplication::InitTrVars()
{
if (trVars == nullptr)
{
trVars = new VTranslateVars(ValentinaSettings()->GetOsSeparator());
trVars = new VTranslateVars();
}
}

View file

@ -33,6 +33,7 @@
#include "../vwidgets/vgraphicssimpletextitem.h"
#include "../vwidgets/vcontrolpointspline.h"
#include "../vwidgets/vsimplepoint.h"
#include "../vwidgets/vsimplecurve.h"
#include "../vpropertyexplorer/vproperties.h"
#include "vformulaproperty.h"
#include "../vpatterndb/vformula.h"
@ -74,7 +75,7 @@ void VToolOptionsPropertyBrowser::ClearPropertyBrowser()
void VToolOptionsPropertyBrowser::ShowItemOptions(QGraphicsItem *item)
{
// This check helps to find missed tools in the switch
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 42, "Not all tools was used in switch.");
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 43, "Not all tools was used in switch.");
switch (item->type())
{
@ -174,9 +175,16 @@ void VToolOptionsPropertyBrowser::ShowItemOptions(QGraphicsItem *item)
currentItem = item->parentItem();
ShowItemOptions(currentItem);
break;
case VSimpleCurve::Type:
currentItem = item->parentItem();
ShowItemOptions(currentItem);
break;
case VToolTrueDarts::Type:
ShowOptionsToolTrueDarts(item);
break;
case VToolRotation::Type:
ShowOptionsToolRotation(item);
break;
default:
break;
}
@ -191,7 +199,7 @@ void VToolOptionsPropertyBrowser::UpdateOptions()
}
// This check helps to find missed tools in the switch
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 42, "Not all tools was used in switch.");
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 43, "Not all tools was used in switch.");
switch (currentItem->type())
{
@ -288,6 +296,9 @@ void VToolOptionsPropertyBrowser::UpdateOptions()
case VToolTrueDarts::Type:
UpdateOptionsToolTrueDarts();
break;
case VToolRotation::Type:
UpdateOptionsToolRotation();
break;
default:
break;
}
@ -323,7 +334,7 @@ void VToolOptionsPropertyBrowser::userChangedData(VProperty *property)
}
// This check helps to find missed tools in the switch
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 42, "Not all tools was used in switch.");
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 43, "Not all tools was used in switch.");
switch (currentItem->type())
{
@ -414,6 +425,9 @@ void VToolOptionsPropertyBrowser::userChangedData(VProperty *property)
case VToolTrueDarts::Type:
ChangeDataToolTrueDarts(prop);
break;
case VToolRotation::Type:
ChangeDataToolRotation(prop);
break;
default:
break;
}
@ -481,7 +495,6 @@ void VToolOptionsPropertyBrowser::AddPropertyObjectName(Tool *i, const QString &
AddProperty(itemName, AttrName);
}
//---------------------------------------------------------------------------------------------------------------------
template<class Tool>
void VToolOptionsPropertyBrowser::AddPropertyPointName1(Tool *i, const QString &propertyName)
@ -502,6 +515,17 @@ void VToolOptionsPropertyBrowser::AddPropertyPointName2(Tool *i, const QString &
AddProperty(itemName, AttrName2);
}
//---------------------------------------------------------------------------------------------------------------------
template<class Tool>
void VToolOptionsPropertyBrowser::AddPropertyOperationSuffix(Tool *i, const QString &propertyName, bool readOnly)
{
auto itemSuffix = new VStringProperty(propertyName);
itemSuffix->setClearButtonEnable(true);
itemSuffix->setValue(i->Suffix());
itemSuffix->setReadOnly(readOnly);
AddProperty(itemSuffix, AttrSuffix);
}
//---------------------------------------------------------------------------------------------------------------------
template<class Tool>
void VToolOptionsPropertyBrowser::AddPropertyCrossPoint(Tool *i, const QString &propertyName)
@ -645,6 +669,43 @@ void VToolOptionsPropertyBrowser::SetPointName2(const QString &name)
}
}
//---------------------------------------------------------------------------------------------------------------------
template<class Tool>
void VToolOptionsPropertyBrowser::SetOperationSuffix(const QString &suffix)
{
if (Tool *item = qgraphicsitem_cast<Tool *>(currentItem))
{
if (suffix == item->Suffix())
{
return;
}
if (suffix.isEmpty())
{
idToProperty[AttrSuffix]->setValue(item->Suffix());
return;
}
QRegularExpression rx(NameRegExp());
const QStringList uniqueNames = VContainer::AllUniqueNames();
for (int i=0; i < uniqueNames.size(); ++i)
{
const QString name = uniqueNames.at(i) + suffix;
if (not rx.match(name).hasMatch() || not VContainer::IsUnique(name))
{
idToProperty[AttrSuffix]->setValue(item->Suffix());
return;
}
}
item->SetSuffix(suffix);
}
else
{
qWarning()<<"Can't cast item";
}
}
//---------------------------------------------------------------------------------------------------------------------
template<class Type>
Type VToolOptionsPropertyBrowser::GetCrossPoint(const QVariant &value)
@ -934,9 +995,6 @@ void VToolOptionsPropertyBrowser::ChangeDataToolCutArc(VProperty *property)
case 4: // AttrLength
i->SetFormula(value.value<VFormula>());
break;
case 27: // AttrTypeColor
i->SetLineColor(value.toString());
break;
default:
qWarning()<<"Unknown property type. id = "<<id;
break;
@ -961,9 +1019,6 @@ void VToolOptionsPropertyBrowser::ChangeDataToolCutSpline(VProperty *property)
case 4: // AttrLength
i->SetFormula(value.value<VFormula>());
break;
case 27: // AttrTypeColor
i->SetLineColor(value.toString());
break;
default:
qWarning()<<"Unknown property type. id = "<<id;
break;
@ -988,9 +1043,6 @@ void VToolOptionsPropertyBrowser::ChangeDataToolCutSplinePath(VProperty *propert
case 4: // AttrLength
i->SetFormula(value.value<VFormula>());
break;
case 27: // AttrTypeColor
i->SetLineColor(value.toString());
break;
default:
qWarning()<<"Unknown property type. id = "<<id;
break;
@ -1525,6 +1577,30 @@ void VToolOptionsPropertyBrowser::ChangeDataToolCurveIntersectAxis(VProperty *pr
}
}
//---------------------------------------------------------------------------------------------------------------------
void VToolOptionsPropertyBrowser::ChangeDataToolRotation(VProperty *property)
{
SCASSERT(property != nullptr)
QVariant value = property->data(VProperty::DPC_Data, Qt::DisplayRole);
const QString id = propertyToId[property];
VToolRotation *i = qgraphicsitem_cast<VToolRotation *>(currentItem);
SCASSERT(i != nullptr);
switch (PropertiesList().indexOf(id))
{
case 38: // AttrSuffix
SetOperationSuffix<VToolRotation>(value.toString());
break;
case 5: // AttrAngle
i->SetFormulaAngle(value.value<VFormula>());
break;
default:
qWarning()<<"Unknown property type. id = "<<id;
break;
}
}
//---------------------------------------------------------------------------------------------------------------------
void VToolOptionsPropertyBrowser::ShowOptionsToolSinglePoint(QGraphicsItem *item)
{
@ -1625,7 +1701,6 @@ void VToolOptionsPropertyBrowser::ShowOptionsToolCutArc(QGraphicsItem *item)
AddPropertyObjectName(i, tr("Point label"));
AddPropertyFormula(tr("Length"), i->GetFormula(), AttrLength);
AddPropertyLineColor(i, tr("Color"), VAbstractTool::ColorsList(), AttrColor);
}
//---------------------------------------------------------------------------------------------------------------------
@ -1637,7 +1712,6 @@ void VToolOptionsPropertyBrowser::ShowOptionsToolCutSpline(QGraphicsItem *item)
AddPropertyObjectName(i, tr("Point label"));
AddPropertyFormula(tr("Length"), i->GetFormula(), AttrLength);
AddPropertyLineColor(i, tr("Color"), VAbstractTool::ColorsList(), AttrColor);
}
//---------------------------------------------------------------------------------------------------------------------
@ -1649,7 +1723,6 @@ void VToolOptionsPropertyBrowser::ShowOptionsToolCutSplinePath(QGraphicsItem *it
AddPropertyObjectName(i, tr("Point label"));
AddPropertyFormula(tr("Length"), i->GetFormula(), AttrLength);
AddPropertyLineColor(i, tr("Color"), VAbstractTool::ColorsList(), AttrColor);
}
//---------------------------------------------------------------------------------------------------------------------
@ -1907,6 +1980,17 @@ void VToolOptionsPropertyBrowser::ShowOptionsToolCurveIntersectAxis(QGraphicsIte
AddPropertyFormula(tr("Angle"), i->GetFormulaAngle(), AttrAngle);
}
//---------------------------------------------------------------------------------------------------------------------
void VToolOptionsPropertyBrowser::ShowOptionsToolRotation(QGraphicsItem *item)
{
VToolRotation *i = qgraphicsitem_cast<VToolRotation *>(item);
i->ShowVisualization(true);
formView->setTitle(tr("Tool rotation"));
AddPropertyOperationSuffix(i, tr("Suffix"));
AddPropertyFormula(tr("Angle"), i->GetFormulaAngle(), AttrAngle);
}
//---------------------------------------------------------------------------------------------------------------------
void VToolOptionsPropertyBrowser::UpdateOptionsToolSinglePoint()
{
@ -2044,9 +2128,6 @@ void VToolOptionsPropertyBrowser::UpdateOptionsToolCutArc()
QVariant valueFormula;
valueFormula.setValue(i->GetFormula());
idToProperty[AttrLength]->setValue(valueFormula);
const qint32 index = VLineColorProperty::IndexOfColor(VAbstractTool::ColorsList(), i->GetLineColor());
idToProperty[AttrColor]->setValue(index);
}
//---------------------------------------------------------------------------------------------------------------------
@ -2059,9 +2140,6 @@ void VToolOptionsPropertyBrowser::UpdateOptionsToolCutSpline()
QVariant valueFormula;
valueFormula.setValue(i->GetFormula());
idToProperty[AttrLength]->setValue(valueFormula);
const qint32 index = VLineColorProperty::IndexOfColor(VAbstractTool::ColorsList(), i->GetLineColor());
idToProperty[AttrColor]->setValue(index);
}
//---------------------------------------------------------------------------------------------------------------------
@ -2074,9 +2152,6 @@ void VToolOptionsPropertyBrowser::UpdateOptionsToolCutSplinePath()
QVariant valueFormula;
valueFormula.setValue(i->GetFormula());
idToProperty[AttrLength]->setValue(valueFormula);
const qint32 index = VLineColorProperty::IndexOfColor(VAbstractTool::ColorsList(), i->GetLineColor());
idToProperty[AttrColor]->setValue(index);
}
//---------------------------------------------------------------------------------------------------------------------
@ -2365,6 +2440,17 @@ void VToolOptionsPropertyBrowser::UpdateOptionsToolCurveIntersectAxis()
idToProperty[AttrAngle]->setValue(valueAngle);
}
//---------------------------------------------------------------------------------------------------------------------
void VToolOptionsPropertyBrowser::UpdateOptionsToolRotation()
{
VToolRotation *i = qgraphicsitem_cast<VToolRotation *>(currentItem);
idToProperty[AttrSuffix]->setValue(i->Suffix());
QVariant valueAngle;
valueAngle.setValue(i->GetFormulaAngle());
idToProperty[AttrAngle]->setValue(valueAngle);
}
//---------------------------------------------------------------------------------------------------------------------
QStringList VToolOptionsPropertyBrowser::PropertiesList() const
{
@ -2405,6 +2491,7 @@ QStringList VToolOptionsPropertyBrowser::PropertiesList() const
<< AttrVCrossPoint /* 34 */
<< AttrHCrossPoint /* 35 */
<< AttrLength1 /* 36 */
<< AttrLength2; /* 37 */
<< AttrLength2 /* 37 */
<< AttrSuffix; /* 38 */
return attr;
}

View file

@ -74,6 +74,9 @@ private:
template<class Tool>
void SetPointName2(const QString &name);
template<class Tool>
void SetOperationSuffix(const QString &suffix);
template<class Type>
Type GetCrossPoint(const QVariant &value);
@ -95,6 +98,9 @@ private:
template<class Tool>
void AddPropertyPointName2(Tool *i, const QString &propertyName);
template<class Tool>
void AddPropertyOperationSuffix(Tool *i, const QString &propertyName, bool readOnly = false);
template<class Tool>
void AddPropertyCrossPoint(Tool *i, const QString &propertyName);
@ -144,6 +150,7 @@ private:
void ChangeDataToolTriangle(VPE::VProperty *property);
void ChangeDataToolLineIntersectAxis(VPE::VProperty *property);
void ChangeDataToolCurveIntersectAxis(VPE::VProperty *property);
void ChangeDataToolRotation(VPE::VProperty *property);
void ShowOptionsToolSinglePoint(QGraphicsItem *item);
void ShowOptionsToolEndLine(QGraphicsItem *item);
@ -174,6 +181,7 @@ private:
void ShowOptionsToolTriangle(QGraphicsItem *item);
void ShowOptionsToolLineIntersectAxis(QGraphicsItem *item);
void ShowOptionsToolCurveIntersectAxis(QGraphicsItem *item);
void ShowOptionsToolRotation(QGraphicsItem *item);
void UpdateOptionsToolSinglePoint();
void UpdateOptionsToolEndLine();
@ -204,6 +212,7 @@ private:
void UpdateOptionsToolTriangle();
void UpdateOptionsToolLineIntersectAxis();
void UpdateOptionsToolCurveIntersectAxis();
void UpdateOptionsToolRotation();
};
#endif // VTOOLOPTIONSPROPERTYBROWSER_H

View file

@ -208,7 +208,7 @@ void DialogHistory::FillTable()
QString DialogHistory::Record(const VToolRecord &tool)
{
// This check helps to find missed tools in the switch
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 42, "Not all tools was used in history.");
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 43, "Not all tools was used in history.");
const QDomElement domElem = doc->elementById(tool.getId());
if (domElem.isElement() == false)
@ -335,7 +335,7 @@ QString DialogHistory::Record(const VToolRecord &tool)
case Tool::CutSpline:
{
const quint32 splineId = AttrUInt(domElem, VToolCutSpline::AttrSpline);
const QSharedPointer<VSpline> spl = data->GeometricObject<VSpline>(splineId);
const QSharedPointer<VAbstractCubicBezier> spl = data->GeometricObject<VAbstractCubicBezier>(splineId);
SCASSERT(spl != nullptr);
return QString(tr("%1 - cut %2"))
.arg(PointName(tool.getId()))
@ -344,7 +344,8 @@ QString DialogHistory::Record(const VToolRecord &tool)
case Tool::CutSplinePath:
{
const quint32 splinePathId = AttrUInt(domElem, VToolCutSplinePath::AttrSplinePath);
const QSharedPointer<VSplinePath> splPath = data->GeometricObject<VSplinePath>(splinePathId);
const QSharedPointer<VAbstractCubicBezierPath> splPath =
data->GeometricObject<VAbstractCubicBezierPath>(splinePathId);
SCASSERT(splPath != nullptr);
return QString(tr("%1 - cut %2"))
.arg(PointName(tool.getId()))
@ -384,6 +385,7 @@ QString DialogHistory::Record(const VToolRecord &tool)
case Tool::NodeSpline:
case Tool::NodeSplinePath:
case Tool::Group:
case Tool::Rotation:
return QString();
}
}

View file

@ -42,6 +42,7 @@
#include <QTableWidget>
#include <QSettings>
#include <QTableWidgetItem>
#include <QtNumeric>
#define DIALOG_MAX_FORMULA_HEIGHT 64
@ -143,7 +144,7 @@ void DialogIncrements::FillIncrements()
QString formula;
try
{
formula = qApp->TrVars()->FormulaToUser(incr->GetFormula());
formula = qApp->TrVars()->FormulaToUser(incr->GetFormula(), qApp->Settings()->GetOsSeparator());
}
catch (qmu::QmuParserError &e)
{
@ -309,9 +310,15 @@ bool DialogIncrements::EvalIncrementFormula(const QString &formula, bool fromUse
f = formula;
}
f.replace("\n", " ");
Calculator *cal = new Calculator();
QScopedPointer<Calculator> cal(new Calculator());
const qreal result = cal->EvalFormula(data->PlainVariables(), f);
delete cal;
if (qIsInf(result) || qIsNaN(result))
{
label->setText(tr("Error") + " (" + postfix + ").");
label->setToolTip(tr("Invalid value"));
return false;
}
label->setText(qApp->LocaleToString(result) + " " + postfix);
label->setToolTip(tr("Value"));
@ -681,6 +688,9 @@ void DialogIncrements::Fx()
if (dialog->exec() == QDialog::Accepted)
{
// Fix the bug #492. https://bitbucket.org/dismine/valentina/issues/492/valentina-crashes-when-add-an-increment
// Because of the bug need to take QTableWidgetItem twice time. Previous update "killed" the pointer.
const QTableWidgetItem *nameField = ui->tableWidgetIncrement->item(row, 0);
doc->SetIncrementFormula(nameField->text(), dialog->GetFormula());
FullUpdateTree(Document::LiteParse);
ui->tableWidgetIncrement->selectRow(row);
@ -748,7 +758,7 @@ void DialogIncrements::ShowIncrementDetails()
QString formula;
try
{
formula = qApp->TrVars()->FormulaToUser(incr->GetFormula());
formula = qApp->TrVars()->FormulaToUser(incr->GetFormula(), qApp->Settings()->GetOsSeparator());
}
catch (qmu::QmuParserError &e)
{

View file

@ -130,17 +130,8 @@ MainWindow::MainWindow(QWidget *parent)
}
CreateActions();
CreateMenus();
ToolBarDraws();
ToolBarStages();
InitToolButtons();
InitScenes();
helpLabel = new QLabel(QObject::tr("Create new pattern piece to start working."));
ui->statusBar->addWidget(helpLabel);
ToolBarTools();
doc = new VPattern(pattern, &mode, sceneDraw, sceneDetails);
connect(doc, &VPattern::ClearMainWindow, this, &MainWindow::Clear);
connect(doc, &VPattern::patternChanged, this, &MainWindow::PatternWasModified);
@ -150,6 +141,17 @@ MainWindow::MainWindow(QWidget *parent)
connect(doc, &VPattern::SetCurrentPP, this, &MainWindow::GlobalChangePP);
qApp->setCurrentDocument(doc);
InitDocksContain();
CreateMenus();
ToolBarDraws();
ToolBarStages();
InitToolButtons();
helpLabel = new QLabel(QObject::tr("Create new pattern piece to start working."));
ui->statusBar->addWidget(helpLabel);
ToolBarTools();
connect(qApp->getUndoStack(), &QUndoStack::cleanChanged, this, &MainWindow::PatternWasModified);
InitAutoSave();
@ -157,7 +159,6 @@ MainWindow::MainWindow(QWidget *parent)
ui->toolBox->setCurrentIndex(0);
ReadSettings();
InitDocksContain();
setCurrentFile("");
WindowsLocale();
@ -613,6 +614,7 @@ void MainWindow::SetToolButtonWithApply(bool checked, Tool t, const QString &cur
SCASSERT(scene != nullptr);
connect(scene, &VMainGraphicsScene::ChoosedObject, dialogTool, &DialogTool::ChosenObject);
connect(scene, &VMainGraphicsScene::SelectedObject, dialogTool, &DialogTool::SelectedObject);
connect(dialogTool, &DialogTool::DialogClosed, this, closeDialogSlot);
connect(dialogTool, &DialogTool::DialogApplied, this, applyDialogSlot);
connect(dialogTool, &DialogTool::ToolTip, this, &MainWindow::ShowToolTip);
@ -1004,12 +1006,22 @@ void MainWindow::ClosedDialogUnionDetails(int result)
void MainWindow::ToolGroup(bool checked)
{
ToolSelectGroupObjects();
currentScene->clearSelection();
SetToolButton<DialogGroup>(checked, Tool::Group, ":/cursor/group_plus_cursor.png",
tr("Select one or more objects, <b>Enter</b> - finish creation"),
&MainWindow::ClosedDialogGroup);
}
//---------------------------------------------------------------------------------------------------------------------
void MainWindow::ToolRotation(bool checked)
{
ToolSelectOperationObjects();
SetToolButtonWithApply<DialogRotation>(checked, Tool::Rotation,
":/cursor/rotation_cursor.png",
tr("Select one or more objects, <b>Enter</b> - confirm selection"),
&MainWindow::ClosedDialogWithApply<VToolRotation>,
&MainWindow::ApplyDialog<VToolRotation>);
}
//---------------------------------------------------------------------------------------------------------------------
void MainWindow::ClosedDialogGroup(int result)
{
@ -1737,6 +1749,7 @@ void MainWindow::InitToolButtons()
connect(ui->toolButtonArcWithLength, &QToolButton::clicked, this, &MainWindow::ToolArcWithLength);
connect(ui->toolButtonTrueDarts, &QToolButton::clicked, this, &MainWindow::ToolTrueDarts);
connect(ui->toolButtonGroup, &QToolButton::clicked, this, &MainWindow::ToolGroup);
connect(ui->toolButtonRotation, &QToolButton::clicked, this, &MainWindow::ToolRotation);
}
//---------------------------------------------------------------------------------------------------------------------
@ -1777,12 +1790,16 @@ void MainWindow::mouseMove(const QPointF &scenePos)
void MainWindow::CancelTool()
{
// This check helps to find missed tools in the switch
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 42, "Not all tools was handled.");
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 43, "Not all tools was handled.");
qCDebug(vMainWindow, "Canceling tool.");
delete dialogTool;
dialogTool = nullptr;
qCDebug(vMainWindow, "Dialog closed.");
currentScene->setFocus(Qt::OtherFocusReason);
currentScene->clearSelection();
switch ( currentTool )
{
case Tool::Arrow:
@ -1904,9 +1921,10 @@ void MainWindow::CancelTool()
case Tool::Group:
ui->toolButtonGroup->setChecked(false);
break;
case Tool::Rotation:
ui->toolButtonRotation->setChecked(false);
break;
}
currentScene->setFocus(Qt::OtherFocusReason);
currentScene->clearSelection();
// Crash: using CRTL+Z while using line tool.
// related bug report:
@ -3109,6 +3127,7 @@ void MainWindow::SetEnableTool(bool enable)
ui->toolButtonArcWithLength->setEnabled(drawTools);
ui->toolButtonTrueDarts->setEnabled(drawTools);
ui->toolButtonGroup->setEnabled(drawTools);
ui->toolButtonRotation->setEnabled(drawTools);
ui->actionLast_tool->setEnabled(drawTools);
@ -3353,12 +3372,14 @@ void MainWindow::CreateMenus()
//Add Undo/Redo actions.
undoAction = qApp->getUndoStack()->createUndoAction(this, tr("&Undo"));
connect(undoAction, &QAction::triggered, toolOptions, &VToolOptionsPropertyBrowser::RefreshOptions);
undoAction->setShortcuts(QKeySequence::Undo);
undoAction->setIcon(QIcon::fromTheme("edit-undo"));
ui->menuPatternPiece->insertAction(ui->actionLast_tool, undoAction);
ui->toolBarTools->addAction(undoAction);
redoAction = qApp->getUndoStack()->createRedoAction(this, tr("&Redo"));
connect(redoAction, &QAction::triggered, toolOptions, &VToolOptionsPropertyBrowser::RefreshOptions);
redoAction->setShortcuts(QKeySequence::Redo);
redoAction->setIcon(QIcon::fromTheme("edit-redo"));
ui->menuPatternPiece->insertAction(ui->actionLast_tool, redoAction);
@ -3379,7 +3400,7 @@ void MainWindow::CreateMenus()
void MainWindow::LastUsedTool()
{
// This check helps to find missed tools in the switch
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 42, "Not all tools was handled.");
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 43, "Not all tools was handled.");
if (currentTool == lastUsedTool)
{
@ -3530,6 +3551,10 @@ void MainWindow::LastUsedTool()
ui->toolButtonGroup->setChecked(true);
ToolGroup(true);
break;
case Tool::Rotation:
ui->toolButtonRotation->setChecked(true);
ToolRotation(true);
break;
}
}
@ -4714,12 +4739,12 @@ void MainWindow::ToolSelectAllDrawObjects() const
}
//---------------------------------------------------------------------------------------------------------------------
void MainWindow::ToolSelectGroupObjects() const
void MainWindow::ToolSelectOperationObjects() const
{
// Only true for rubber band selection
emit EnableLabelSelection(true);
emit EnablePointSelection(true);
emit EnableLineSelection(true);
emit EnableLineSelection(false);
emit EnableArcSelection(true);
emit EnableSplineSelection(true);
emit EnableSplinePathSelection(true);
@ -4727,7 +4752,7 @@ void MainWindow::ToolSelectGroupObjects() const
// Hovering
emit EnableLabelHover(true);
emit EnablePointHover(true);
emit EnableLineHover(true);
emit EnableLineHover(false);
emit EnableArcHover(true);
emit EnableSplineHover(true);
emit EnableSplinePathHover(true);
@ -4737,6 +4762,17 @@ void MainWindow::ToolSelectGroupObjects() const
ui->view->AllowRubberBand(true);
}
//---------------------------------------------------------------------------------------------------------------------
void MainWindow::ToolSelectGroupObjects() const
{
ToolSelectOperationObjects();
// Only true for rubber band selection
emit EnableLineSelection(true);
// Hovering
emit EnableLineHover(true);
}
//---------------------------------------------------------------------------------------------------------------------
void MainWindow::ToolSelectDetail() const
{

View file

@ -122,6 +122,7 @@ public slots:
void ToolPointOfIntersection(bool checked);
void ToolUnionDetails(bool checked);
void ToolGroup(bool checked);
void ToolRotation(bool checked);
void ToolCutArc(bool checked);
void ToolLineIntersectAxis(bool checked);
void ToolCurveIntersectAxis(bool checked);
@ -372,6 +373,7 @@ private:
void ToolSelectPointArc() const;
void ToolSelectCurve() const;
void ToolSelectAllDrawObjects() const;
void ToolSelectOperationObjects() const;
void ToolSelectGroupObjects() const;
void ToolSelectDetail() const;
};

View file

@ -983,6 +983,32 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="toolButtonRotation">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Rotate objects</string>
</property>
<property name="text">
<string notr="true">...</string>
</property>
<property name="icon">
<iconset resource="share/resources/toolicon.qrc">
<normaloff>:/toolicon/32x32/rotation.png</normaloff>:/toolicon/32x32/rotation.png</iconset>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_5">

View file

@ -66,5 +66,7 @@
<file>cursor/cubic_bezier_path_cursor@2x.png</file>
<file>cursor/group_plus_cursor.png</file>
<file>cursor/group_plus_cursor@2x.png</file>
<file>cursor/rotation_cursor.png</file>
<file>cursor/rotation_cursor@2x.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 836 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -64,5 +64,7 @@
<file>toolicon/32x32/cubic_bezier_path@2x.png</file>
<file>toolicon/32x32/group_plus.png</file>
<file>toolicon/32x32/group_plus@2x.png</file>
<file>toolicon/32x32/rotation.png</file>
<file>toolicon/32x32/rotation@2x.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64mm"
height="64mm"
viewBox="0 0 226.77165 226.77165"
id="svg2"
version="1.1"
inkscape:version="0.91 r"
sodipodi:docname="rotation.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2"
inkscape:cx="95.256309"
inkscape:cy="193.75942"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1855"
inkscape:window-height="1056"
inkscape:window-x="65"
inkscape:window-y="24"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-109.37599,-227.40381)">
<g
id="g4161"
transform="matrix(1.4799279,0,0,1.514144,-50.49258,-240.01162)">
<path
style="fill:#4c4c4e"
d="m 175.63227,452.76646 c -4.46875,-0.93774 -11.21875,-3.08929 -15,-4.78121 -8.24709,-3.69017 -21.35406,-13.37364 -24.40567,-18.03098 -2.17124,-3.31373 -2.15358,-3.39279 1.41601,-6.34044 8.98492,-7.41942 8.5619,-7.37711 15.15272,-1.51551 7.49569,6.66635 18.87856,12.10104 29.12615,13.90613 15.6875,2.76328 32.5699,-2.90492 44.78685,-15.03701 21.30761,-21.15965 21.42043,-54.09472 0.25774,-75.24597 -16.4986,-16.48969 -40.34704,-20.56179 -61.06292,-10.42646 -7.89028,3.86036 -20.27088,15.13215 -20.27088,18.45542 0,1.46429 2.69199,3.44216 8.18114,6.01083 4.49962,2.10564 7.97069,4.45977 7.71347,5.2314 -0.76092,2.28276 -43.5192,27.43921 -44.63742,26.26202 -0.85926,-0.90458 -7.53255,-46.56479 -7.51343,-51.40866 0.004,-1.03123 2.60033,-0.271 7.47059,2.1875 4.1054,2.07239 8.48533,3.76799 9.73318,3.76799 1.26595,0 4.32338,-2.75199 6.91685,-6.22583 8.0603,-10.79646 20.45023,-19.26242 35.88562,-24.52041 9.52071,-3.2432 30.42538,-3.25368 40,-0.0201 24.10475,8.14083 41.33866,25.60172 48.25576,48.8913 3.36888,11.34283 3.081,28.84652 -0.6646,40.40947 -11.1378,34.38337 -46.87719,55.6626 -81.34116,48.4305 z"
id="path3349"
inkscape:connector-curvature="0" />
<path
d="m 205.99674,384.45563 a 16.359516,16.624689 0 0 1 -16.33832,16.62467 16.359516,16.624689 0 0 1 -16.38066,-16.58158 16.359516,16.624689 0 0 1 16.29586,-16.66766 16.359516,16.624689 0 0 1 16.4229,16.53839"
sodipodi:open="true"
sodipodi:end="6.2780017"
sodipodi:start="0"
sodipodi:ry="16.624689"
sodipodi:rx="16.359516"
sodipodi:cy="384.45563"
sodipodi:cx="189.63722"
sodipodi:type="arc"
id="path3357"
style="opacity:1;fill:#da4d3b;fill-opacity:1;fill-rule:evenodd;stroke:#da4d3b;stroke-width:1.82180572;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.9000001;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -51,6 +51,7 @@
#include <QMessageBox>
#include <QUndoStack>
#include <QtCore/qmath.h>
#include <QtNumeric>
const QString VPattern::AttrReadOnly = QStringLiteral("readOnly");
@ -305,8 +306,7 @@ quint32 VPattern::SPointActiveDraw()
const QDomElement domElement = domNode.toElement();
if (domElement.isNull() == false)
{
if (domElement.tagName() == VToolSinglePoint::TagName &&
domElement.attribute(AttrType, "") == VToolBasePoint::ToolType)
if (domElement.tagName() == TagPoint && domElement.attribute(AttrType, "") == VToolBasePoint::ToolType)
{
return GetParametrId(domElement);
}
@ -527,7 +527,7 @@ void VPattern::ParseDrawMode(const QDomNode &node, const Document &parse, const
{
scene = sceneDetail;
}
QStringList tags = QStringList() << TagPoint << TagLine << TagSpline << TagArc << TagTools;
const QStringList tags = QStringList() << TagPoint << TagLine << TagSpline << TagArc << TagTools << TagOperation;
const QDomNodeList nodeList = node.childNodes();
const qint32 num = nodeList.size();
for (qint32 i = 0; i < num; ++i)
@ -557,6 +557,10 @@ void VPattern::ParseDrawMode(const QDomNode &node, const Document &parse, const
qCDebug(vXML, "Tag tools.");
ParseToolsElement(scene, domElement, parse, domElement.attribute(AttrType, ""));
break;
case 5: // TagOperation
qCDebug(vXML, "Tag operation.");
ParseOperationElement(scene, domElement, parse, domElement.attribute(AttrType, ""));
break;
default:
VException e(tr("Wrong tag name '%1'.").arg(domElement.tagName()));
throw e;
@ -596,7 +600,7 @@ void VPattern::ParseDetailElement(const QDomElement &domElement, const Document
{
if (element.tagName() == VToolDetail::TagNode)
{
const quint32 id = GetParametrUInt(element, VToolDetail::AttrIdObject, NULL_ID_STR);
const quint32 id = GetParametrUInt(element, AttrIdObject, NULL_ID_STR);
const qreal mx = qApp->toPixel(GetParametrDouble(element, AttrMx, "0.0"));
const qreal my = qApp->toPixel(GetParametrDouble(element, AttrMy, "0.0"));
const bool reverse = GetParametrUInt(element, VToolDetail::AttrReverse, "0");
@ -654,7 +658,7 @@ void VPattern::ParseDetails(const QDomElement &domElement, const Document &parse
const QDomElement domElement = domNode.toElement();
if (domElement.isNull() == false)
{
if (domElement.tagName() == VToolDetail::TagName)
if (domElement.tagName() == TagDetail)
{
ParseDetailElement(domElement, parse);
}
@ -840,7 +844,7 @@ void VPattern::ParseLineElement(VMainGraphicsScene *scene, const QDomElement &do
void VPattern::SplinesCommonAttributes(const QDomElement &domElement, quint32 &id, quint32 &idObject, quint32 &idTool)
{
ToolsCommonAttributes(domElement, id);
idObject = GetParametrUInt(domElement, VAbstractNode::AttrIdObject, NULL_ID_STR);
idObject = GetParametrUInt(domElement, AttrIdObject, NULL_ID_STR);
idTool = GetParametrUInt(domElement, VAbstractNode::AttrIdTool, NULL_ID_STR);
}
@ -1279,7 +1283,7 @@ void VPattern::ParseNodePoint(const QDomElement &domElement, const Document &par
qreal my = 0;
PointsCommonAttributes(domElement, id, mx, my);
const quint32 idObject = GetParametrUInt(domElement, VAbstractNode::AttrIdObject, NULL_ID_STR);
const quint32 idObject = GetParametrUInt(domElement, AttrIdObject, NULL_ID_STR);
const quint32 idTool = GetParametrUInt(domElement, VAbstractNode::AttrIdTool, NULL_ID_STR);
QSharedPointer<VPointF> point;
try
@ -1291,8 +1295,7 @@ void VPattern::ParseNodePoint(const QDomElement &domElement, const Document &par
Q_UNUSED(e);
return;// Just ignore
}
data->UpdateGObject(id, new VPointF(point->toQPointF(), point->name(), mx, my, idObject,
Draw::Modeling));
data->UpdateGObject(id, new VPointF(*point, point->name(), mx, my, idObject, Draw::Modeling));
VNodePoint::Create(this, data, sceneDetail, id, idObject, parse, Source::FromFile, idTool);
}
catch (const VExceptionBadId &e)
@ -1410,11 +1413,8 @@ void VPattern::ParseToolCutSpline(VMainGraphicsScene *scene, QDomElement &domEle
const QString formula = GetParametrString(domElement, AttrLength, "0");
QString f = formula;//need for saving fixed formula;
const quint32 splineId = GetParametrUInt(domElement, VToolCutSpline::AttrSpline, NULL_ID_STR);
const QString color = GetParametrString(domElement, AttrColor,
ColorBlack);
VToolCutSpline::Create(id, name, f, splineId, mx, my, color, scene, this, data, parse,
Source::FromFile);
VToolCutSpline::Create(id, name, f, splineId, mx, my, scene, this, data, parse, Source::FromFile);
//Rewrite attribute formula. Need for situation when we have wrong formula.
if (f != formula)
{
@ -1455,11 +1455,8 @@ void VPattern::ParseToolCutSplinePath(VMainGraphicsScene *scene, QDomElement &do
QString f = formula;//need for saving fixed formula;
const quint32 splinePathId = GetParametrUInt(domElement, VToolCutSplinePath::AttrSplinePath,
NULL_ID_STR);
const QString color = GetParametrString(domElement, AttrColor,
ColorBlack);
VToolCutSplinePath::Create(id, name, f, splinePathId, mx, my, color, scene, this, data, parse,
Source::FromFile);
VToolCutSplinePath::Create(id, name, f, splinePathId, mx, my, scene, this, data, parse, Source::FromFile);
//Rewrite attribute formula. Need for situation when we have wrong formula.
if (f != formula)
{
@ -1499,9 +1496,8 @@ void VPattern::ParseToolCutArc(VMainGraphicsScene *scene, QDomElement &domElemen
const QString formula = GetParametrString(domElement, AttrLength, "0");
QString f = formula;//need for saving fixed formula;
const quint32 arcId = GetParametrUInt(domElement, AttrArc, NULL_ID_STR);
const QString color = GetParametrString(domElement, AttrColor, ColorBlack);
VToolCutArc::Create(id, name, f, arcId, mx, my, color, scene, this, data, parse, Source::FromFile);
VToolCutArc::Create(id, name, f, arcId, mx, my, scene, this, data, parse, Source::FromFile);
//Rewrite attribute formula. Need for situation when we have wrong formula.
if (f != formula)
{
@ -2330,7 +2326,7 @@ void VPattern::ParseNodeArc(const QDomElement &domElement, const Document &parse
quint32 id = 0;
ToolsCommonAttributes(domElement, id);
const quint32 idObject = GetParametrUInt(domElement, VAbstractNode::AttrIdObject, NULL_ID_STR);
const quint32 idObject = GetParametrUInt(domElement, AttrIdObject, NULL_ID_STR);
const quint32 idTool = GetParametrUInt(domElement, VAbstractNode::AttrIdTool, NULL_ID_STR);
VArc *arc = nullptr;
try
@ -2401,6 +2397,49 @@ void VPattern::ParseToolArcWithLength(VMainGraphicsScene *scene, QDomElement &do
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPattern::ParseToolRotation(VMainGraphicsScene *scene, QDomElement &domElement, const Document &parse)
{
SCASSERT(scene != nullptr);
Q_ASSERT_X(domElement.isNull() == false, Q_FUNC_INFO, "domElement is null");
try
{
quint32 id = NULL_ID;
ToolsCommonAttributes(domElement, id);
const quint32 center = GetParametrUInt(domElement, AttrCenter, NULL_ID_STR);
const QString angle = GetParametrString(domElement, AttrAngle, "10");
QString a = angle;//need for saving fixed formula;
const QString suffix = GetParametrString(domElement, AttrSuffix, "");
QVector<quint32> source;
QVector<DestinationItem> destination;
VToolRotation::ExtractData(this, domElement, source, destination);
VToolRotation::Create(id, center, a, suffix, source, destination, scene, this, data, parse, Source::FromFile);
//Rewrite attribute formula. Need for situation when we have wrong formula.
if (a != angle)
{
SetAttribute(domElement, AttrAngle, a);
modified = true;
haveLiteChange();
}
}
catch (const VExceptionBadId &e)
{
VExceptionObjectError excep(tr("Error creating or updating operation of rotation"), domElement);
excep.AddMoreInformation(e.ErrorMessage());
throw excep;
}
catch (qmu::QmuParserError &e)
{
VExceptionObjectError excep(tr("Error creating or updating operation of rotation"), domElement);
excep.AddMoreInformation(QString("Message: " + e.GetMsg() + "\n"+ "Expression: " + e.GetExpr()));
throw excep;
}
}
//---------------------------------------------------------------------------------------------------------------------
qreal VPattern::EvalFormula(VContainer *data, const QString &formula, bool *ok) const
{
@ -2416,11 +2455,10 @@ qreal VPattern::EvalFormula(VContainer *data, const QString &formula, bool *ok)
// Replace line return character with spaces for calc if exist
QString f = formula;
f.replace("\n", " ");
Calculator *cal = new Calculator();
QScopedPointer<Calculator> cal(new Calculator());
const qreal result = cal->EvalFormula(data->PlainVariables(), f);
delete cal;
*ok = true;
(qIsInf(result) || qIsNaN(result)) ? *ok = false : *ok = true;
return result;
}
catch (qmu::QmuParserError &e)
@ -2644,6 +2682,27 @@ void VPattern::ParseToolsElement(VMainGraphicsScene *scene, const QDomElement &d
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPattern::ParseOperationElement(VMainGraphicsScene *scene, QDomElement &domElement, const Document &parse,
const QString &type)
{
SCASSERT(scene != nullptr);
Q_ASSERT_X(not domElement.isNull(), Q_FUNC_INFO, "domElement is null");
Q_ASSERT_X(not type.isEmpty(), Q_FUNC_INFO, "type of operation is empty");
const QStringList opers = QStringList() << VToolRotation::ToolType; /*0*/
switch (opers.indexOf(type))
{
case 0: //VToolRotation::ToolType
ParseToolRotation(scene, domElement, parse);
break;
default:
VException e(tr("Unknown operation type '%1'.").arg(type));
throw e;
}
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief ParseIncrementsElement parse increments tag.
@ -2814,10 +2873,9 @@ void VPattern::SetIncrementDescription(const QString &name, const QString &text)
*/
QString VPattern::GenerateLabel(const LabelType &type, const QString &reservedName) const
{
QDomNodeList drawList = elementsByTagName(TagDraw);
if (type == LabelType::NewPatternPiece)
{
const QDomNodeList drawList = elementsByTagName(TagDraw);
QString name;
int i = 0;
for (;;)
@ -2838,25 +2896,7 @@ QString VPattern::GenerateLabel(const LabelType &type, const QString &reservedNa
}
else if (type == LabelType::NewLabel)
{
if (drawList.isEmpty())
{
const QString label = GetLabelBase(0);
qCDebug(vXML, "Point label: %s", qUtf8Printable(label));
return label;
}
int index = 0;
for (int i = 0; i < drawList.size(); ++i)
{
QDomElement node = drawList.at(i).toElement();
if (node.attribute(AttrName) == nameActivPP)
{
index = i;
break;
}
}
QString labelBase = GetLabelBase(static_cast<quint32>(index));
const QString labelBase = GetLabelBase(static_cast<quint32>(GetIndexActivPP()));
qint32 num = 1;
QString name;
@ -2876,6 +2916,40 @@ QString VPattern::GenerateLabel(const LabelType &type, const QString &reservedNa
return QString();
}
//---------------------------------------------------------------------------------------------------------------------
QString VPattern::GenerateSuffix() const
{
const QString suffixBase = GetLabelBase(static_cast<quint32>(GetIndexActivPP())).toLower();
const QStringList uniqueNames = data->AllUniqueNames();
qint32 num = 1;
QString suffix;
for (;;)
{
suffix = QString("%1%2").arg(suffixBase).arg(num);
for (int i=0; i < uniqueNames.size(); ++i)
{
if (not data->IsUnique(uniqueNames.at(i) + suffix))
{
break;
}
if (i == uniqueNames.size()-1)
{
qCDebug(vXML, "Suffix is: %s", qUtf8Printable(suffix));
return suffix;
}
}
if (num == INT_MAX)
{
break;
}
++num;
}
return QString();
}
//---------------------------------------------------------------------------------------------------------------------
bool VPattern::IsDefCustom() const
{
@ -3130,7 +3204,7 @@ void VPattern::ToolsCommonAttributes(const QDomElement &domElement, quint32 &id)
QRectF VPattern::ActiveDrawBoundingRect() const
{
// This check helps to find missed tools in the switch
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 42, "Not all tools was used.");
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 43, "Not all tools was used.");
QRectF rec;
@ -3237,6 +3311,9 @@ QRectF VPattern::ActiveDrawBoundingRect() const
case Tool::TrueDarts:
rec = ToolBoundingRect<VToolTrueDarts>(rec, tool.getId());
break;
case Tool::Rotation:
rec = ToolBoundingRect<VToolRotation>(rec, tool.getId());
break;
//These tools are not accesseble in Draw mode, but still 'history' contains them.
case Tool::Detail:
case Tool::UnionDetails:

View file

@ -77,6 +77,7 @@ public:
void SetIncrementDescription(const QString &name, const QString &text);
virtual QString GenerateLabel(const LabelType &type, const QString &reservedName = QString())const Q_DECL_OVERRIDE;
virtual QString GenerateSuffix() const Q_DECL_OVERRIDE;
bool IsDefCustom() const;
void SetDefCustom(bool value);
@ -125,6 +126,8 @@ private:
const Document &parse, const QString& type);
void ParseToolsElement(VMainGraphicsScene *scene, const QDomElement& domElement,
const Document &parse, const QString& type);
void ParseOperationElement(VMainGraphicsScene *scene, QDomElement &domElement, const Document &parse,
const QString& type);
void ParseIncrementsElement(const QDomNode& node);
void PrepareForParse(const Document &parse);
void ToolsCommonAttributes(const QDomElement &domElement, quint32 &id);
@ -185,6 +188,8 @@ private:
void ParseNodeArc(const QDomElement &domElement, const Document &parse);
void ParseToolArcWithLength(VMainGraphicsScene *scene, QDomElement &domElement, const Document &parse);
void ParseToolRotation(VMainGraphicsScene *scene, QDomElement &domElement, const Document &parse);
qreal EvalFormula(VContainer *data, const QString &formula, bool *ok) const;
QDomElement MakeEmptyIncrement(const QString &name);

View file

@ -128,6 +128,8 @@ const QString AttrCCenter = QStringLiteral("cCenter");
const QString AttrTangent = QStringLiteral("tangent");
const QString AttrCRadius = QStringLiteral("cRadius");
const QString AttrArc = QStringLiteral("arc");
const QString AttrSuffix = QStringLiteral("suffix");
const QString AttrIdObject = QStringLiteral("idObject");
const QString TypeLineNone = QStringLiteral("none");
const QString TypeLineLine = QStringLiteral("hair");

View file

@ -130,6 +130,8 @@ extern const QString AttrCCenter;
extern const QString AttrTangent;
extern const QString AttrCRadius;
extern const QString AttrArc;
extern const QString AttrSuffix;
extern const QString AttrIdObject;
extern const QString TypeLineNone;
extern const QString TypeLineLine;

View file

@ -14,6 +14,7 @@
<file>schema/pattern/v0.2.6.xsd</file>
<file>schema/pattern/v0.2.7.xsd</file>
<file>schema/pattern/v0.3.0.xsd</file>
<file>schema/pattern/v0.3.1.xsd</file>
<file>schema/standard_measurements/v0.3.0.xsd</file>
<file>schema/standard_measurements/v0.4.0.xsd</file>
<file>schema/standard_measurements/v0.4.1.xsd</file>

View file

@ -0,0 +1,515 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- XML Schema Generated from XML Document-->
<xs:element name="pattern">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="version" type="formatVersion"></xs:element>
<xs:element name="unit" type="units"></xs:element>
<xs:element name="image" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="extension" type="imageExtension"></xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="author" type="xs:string" minOccurs="0" maxOccurs="1"></xs:element>
<xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1"></xs:element>
<xs:element name="notes" type="xs:string" minOccurs="0" maxOccurs="1"></xs:element>
<xs:element name="gradation" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="heights">
<xs:complexType>
<xs:attribute name="all" type="xs:boolean" use="required"></xs:attribute>
<xs:attribute name="h92" type="xs:boolean"></xs:attribute>
<xs:attribute name="h98" type="xs:boolean"></xs:attribute>
<xs:attribute name="h104" type="xs:boolean"></xs:attribute>
<xs:attribute name="h110" type="xs:boolean"></xs:attribute>
<xs:attribute name="h116" type="xs:boolean"></xs:attribute>
<xs:attribute name="h122" type="xs:boolean"></xs:attribute>
<xs:attribute name="h128" type="xs:boolean"></xs:attribute>
<xs:attribute name="h134" type="xs:boolean"></xs:attribute>
<xs:attribute name="h140" type="xs:boolean"></xs:attribute>
<xs:attribute name="h146" type="xs:boolean"></xs:attribute>
<xs:attribute name="h152" type="xs:boolean"></xs:attribute>
<xs:attribute name="h158" type="xs:boolean"></xs:attribute>
<xs:attribute name="h164" type="xs:boolean"></xs:attribute>
<xs:attribute name="h170" type="xs:boolean"></xs:attribute>
<xs:attribute name="h176" type="xs:boolean"></xs:attribute>
<xs:attribute name="h182" type="xs:boolean"></xs:attribute>
<xs:attribute name="h188" type="xs:boolean"></xs:attribute>
<xs:attribute name="h194" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="sizes">
<xs:complexType>
<xs:attribute name="all" type="xs:boolean" use="required"></xs:attribute>
<xs:attribute name="s22" type="xs:boolean"></xs:attribute>
<xs:attribute name="s24" type="xs:boolean"></xs:attribute>
<xs:attribute name="s26" type="xs:boolean"></xs:attribute>
<xs:attribute name="s28" type="xs:boolean"></xs:attribute>
<xs:attribute name="s30" type="xs:boolean"></xs:attribute>
<xs:attribute name="s32" type="xs:boolean"></xs:attribute>
<xs:attribute name="s34" type="xs:boolean"></xs:attribute>
<xs:attribute name="s36" type="xs:boolean"></xs:attribute>
<xs:attribute name="s38" type="xs:boolean"></xs:attribute>
<xs:attribute name="s40" type="xs:boolean"></xs:attribute>
<xs:attribute name="s42" type="xs:boolean"></xs:attribute>
<xs:attribute name="s44" type="xs:boolean"></xs:attribute>
<xs:attribute name="s46" type="xs:boolean"></xs:attribute>
<xs:attribute name="s48" type="xs:boolean"></xs:attribute>
<xs:attribute name="s50" type="xs:boolean"></xs:attribute>
<xs:attribute name="s52" type="xs:boolean"></xs:attribute>
<xs:attribute name="s54" type="xs:boolean"></xs:attribute>
<xs:attribute name="s56" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="custom" type="xs:boolean"></xs:attribute>
<xs:attribute name="defHeight" type="baseHeight"></xs:attribute>
<xs:attribute name="defSize" type="baseSize"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="measurements" type="xs:string"></xs:element>
<xs:element name="increments" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="increment" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="description" type="xs:string" use="required"></xs:attribute>
<xs:attribute name="name" type="shortName" use="required"></xs:attribute>
<xs:attribute name="formula" type="xs:string" use="required"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="incrementName">
<xs:selector xpath="increment"/>
<xs:field xpath="@name"/>
</xs:unique>
</xs:element>
<xs:element name="draw" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="calculation" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="x" type="xs:double"></xs:attribute>
<xs:attribute name="y" type="xs:double"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="name" type="shortName"></xs:attribute>
<xs:attribute name="firstPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="secondPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="thirdPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="basePoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="pShoulder" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p1Line" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p2Line" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="length" type="xs:string"></xs:attribute>
<xs:attribute name="angle" type="xs:string"></xs:attribute>
<xs:attribute name="typeLine" type="xs:string"></xs:attribute>
<xs:attribute name="splinePath" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="spline" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p1Line1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p1Line2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p2Line1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="p2Line2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="center" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="radius" type="xs:string"></xs:attribute>
<xs:attribute name="axisP1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="axisP2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="arc" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="curve" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="curve1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="curve2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="lineColor" type="colors"></xs:attribute>
<xs:attribute name="color" type="colors"></xs:attribute>
<xs:attribute name="firstArc" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="secondArc" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="crossPoint" type="crossType"></xs:attribute>
<xs:attribute name="vCrossPoint" type="crossType"></xs:attribute>
<xs:attribute name="hCrossPoint" type="crossType"></xs:attribute>
<xs:attribute name="c1Center" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="c2Center" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="c1Radius" type="xs:string"></xs:attribute>
<xs:attribute name="c2Radius" type="xs:string"></xs:attribute>
<xs:attribute name="cRadius" type="xs:string"></xs:attribute>
<xs:attribute name="tangent" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="cCenter" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="name1" type="shortName"></xs:attribute>
<xs:attribute name="mx1" type="xs:double"></xs:attribute>
<xs:attribute name="my1" type="xs:double"></xs:attribute>
<xs:attribute name="name2" type="shortName"></xs:attribute>
<xs:attribute name="mx2" type="xs:double"></xs:attribute>
<xs:attribute name="my2" type="xs:double"></xs:attribute>
<xs:attribute name="point1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="point2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="dartP1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="dartP2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="dartP3" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="baseLineP1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="baseLineP2" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="firstPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="secondPoint" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="typeLine" type="xs:string"></xs:attribute>
<xs:attribute name="lineColor" type="colors"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="operation" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="source" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="item" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="idObject" type="xs:unsignedInt" use="required"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="destination" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="item" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="idObject" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="center" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="angle" type="xs:string"></xs:attribute>
<xs:attribute name="suffix" type="xs:string"></xs:attribute>
<xs:attribute name="type" type="xs:string" use="required"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="arc" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="angle1" type="xs:string"></xs:attribute>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="angle2" type="xs:string"></xs:attribute>
<xs:attribute name="radius" type="xs:string"></xs:attribute>
<xs:attribute name="center" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="color" type="colors"></xs:attribute>
<xs:attribute name="length" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="spline" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="pathPoint" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="kAsm2" type="xs:string"></xs:attribute>
<xs:attribute name="pSpline" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="angle" type="xs:string"></xs:attribute>
<xs:attribute name="angle1" type="xs:string"></xs:attribute>
<xs:attribute name="angle2" type="xs:string"></xs:attribute>
<xs:attribute name="length1" type="xs:string"></xs:attribute>
<xs:attribute name="length2" type="xs:string"></xs:attribute>
<xs:attribute name="kAsm1" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="kCurve" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="kAsm1" type="xs:double"></xs:attribute>
<xs:attribute name="kAsm2" type="xs:double"></xs:attribute>
<xs:attribute name="angle1" type="xs:string"></xs:attribute>
<xs:attribute name="angle2" type="xs:string"></xs:attribute>
<xs:attribute name="length1" type="xs:string"></xs:attribute>
<xs:attribute name="length2" type="xs:string"></xs:attribute>
<xs:attribute name="point1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="point2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="point3" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="point4" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="color" type="colors"></xs:attribute>
<xs:attribute name="duplicate" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="modeling" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="typeObject" type="xs:string"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="idTool" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="inUse" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="arc" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="typeObject" type="xs:string"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="idTool" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="inUse" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="spline" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="typeObject" type="xs:string"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="idTool" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="inUse" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="tools" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="det" minOccurs="2" maxOccurs="2">
<xs:complexType>
<xs:sequence>
<xs:element name="node" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="nodeType" type="xs:string"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="reverse" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="children" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="child" type="xs:unsignedInt" minOccurs="1" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="indexD1" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="indexD2" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="inUse" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="details" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="detail" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="node" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="nodeType" type="xs:string"></xs:attribute>
<xs:attribute name="idObject" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="type" type="xs:string"></xs:attribute>
<xs:attribute name="reverse" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="supplement" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="mx" type="xs:double"></xs:attribute>
<xs:attribute name="my" type="xs:double"></xs:attribute>
<xs:attribute name="width" type="xs:double"></xs:attribute>
<xs:attribute name="name" type="xs:string"></xs:attribute>
<xs:attribute name="closed" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="groups" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="group" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="object" type="xs:unsignedInt"></xs:attribute>
<xs:attribute name="tool" type="xs:unsignedInt"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required"></xs:attribute>
<xs:attribute name="name" type="xs:string"></xs:attribute>
<xs:attribute name="visible" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="readOnly" type="xs:boolean"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:simpleType name="shortName">
<xs:restriction base="xs:string">
<xs:pattern value="^([^0-9*/^+\-=\s()?%:;!.,`'\&quot;]){1,1}([^*/^+\-=\s()?%:;!.,`'\&quot;]){0,}$"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="units">
<xs:restriction base="xs:string">
<xs:enumeration value="mm"/>
<xs:enumeration value="cm"/>
<xs:enumeration value="inch"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="measurementsTypes">
<xs:restriction base="xs:string">
<xs:enumeration value="standard"/>
<xs:enumeration value="individual"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="formatVersion">
<xs:restriction base="xs:string">
<xs:pattern value="^(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))\.(0|([1-9][0-9]*))$"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="imageExtension">
<xs:restriction base="xs:string">
<xs:enumeration value="PNG"/>
<xs:enumeration value="JPG"/>
<xs:enumeration value="BMP"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="colors">
<xs:restriction base="xs:string">
<xs:enumeration value="black"/>
<xs:enumeration value="green"/>
<xs:enumeration value="blue"/>
<xs:enumeration value="darkRed"/>
<xs:enumeration value="darkGreen"/>
<xs:enumeration value="darkBlue"/>
<xs:enumeration value="yellow"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="baseHeight">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="92"/>
<xs:enumeration value="98"/>
<xs:enumeration value="104"/>
<xs:enumeration value="110"/>
<xs:enumeration value="116"/>
<xs:enumeration value="122"/>
<xs:enumeration value="128"/>
<xs:enumeration value="134"/>
<xs:enumeration value="140"/>
<xs:enumeration value="146"/>
<xs:enumeration value="152"/>
<xs:enumeration value="158"/>
<xs:enumeration value="164"/>
<xs:enumeration value="170"/>
<xs:enumeration value="176"/>
<xs:enumeration value="182"/>
<xs:enumeration value="188"/>
<xs:enumeration value="194"/>
<xs:enumeration value="920"/>
<xs:enumeration value="980"/>
<xs:enumeration value="1040"/>
<xs:enumeration value="1100"/>
<xs:enumeration value="1160"/>
<xs:enumeration value="1220"/>
<xs:enumeration value="1280"/>
<xs:enumeration value="1340"/>
<xs:enumeration value="1400"/>
<xs:enumeration value="1460"/>
<xs:enumeration value="1520"/>
<xs:enumeration value="1580"/>
<xs:enumeration value="1640"/>
<xs:enumeration value="1700"/>
<xs:enumeration value="1760"/>
<xs:enumeration value="1820"/>
<xs:enumeration value="1880"/>
<xs:enumeration value="1940"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="baseSize">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="22"/>
<xs:enumeration value="24"/>
<xs:enumeration value="26"/>
<xs:enumeration value="28"/>
<xs:enumeration value="30"/>
<xs:enumeration value="32"/>
<xs:enumeration value="34"/>
<xs:enumeration value="36"/>
<xs:enumeration value="38"/>
<xs:enumeration value="40"/>
<xs:enumeration value="42"/>
<xs:enumeration value="44"/>
<xs:enumeration value="46"/>
<xs:enumeration value="48"/>
<xs:enumeration value="50"/>
<xs:enumeration value="52"/>
<xs:enumeration value="54"/>
<xs:enumeration value="56"/>
<xs:enumeration value="220"/>
<xs:enumeration value="240"/>
<xs:enumeration value="260"/>
<xs:enumeration value="280"/>
<xs:enumeration value="300"/>
<xs:enumeration value="320"/>
<xs:enumeration value="340"/>
<xs:enumeration value="360"/>
<xs:enumeration value="380"/>
<xs:enumeration value="400"/>
<xs:enumeration value="420"/>
<xs:enumeration value="440"/>
<xs:enumeration value="460"/>
<xs:enumeration value="480"/>
<xs:enumeration value="500"/>
<xs:enumeration value="520"/>
<xs:enumeration value="540"/>
<xs:enumeration value="560"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="crossType">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="1"/>
<xs:enumeration value="2"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

View file

@ -38,6 +38,7 @@ const QString VAbstractPattern::TagPattern = QStringLiteral("pattern");
const QString VAbstractPattern::TagCalculation = QStringLiteral("calculation");
const QString VAbstractPattern::TagModeling = QStringLiteral("modeling");
const QString VAbstractPattern::TagDetails = QStringLiteral("details");
const QString VAbstractPattern::TagDetail = QStringLiteral("detail");
const QString VAbstractPattern::TagAuthor = QStringLiteral("author");
const QString VAbstractPattern::TagDescription = QStringLiteral("description");
const QString VAbstractPattern::TagNotes = QStringLiteral("notes");
@ -54,6 +55,7 @@ const QString VAbstractPattern::TagLine = QStringLiteral("line");
const QString VAbstractPattern::TagSpline = QStringLiteral("spline");
const QString VAbstractPattern::TagArc = QStringLiteral("arc");
const QString VAbstractPattern::TagTools = QStringLiteral("tools");
const QString VAbstractPattern::TagOperation = QStringLiteral("operation");
const QString VAbstractPattern::TagGradation = QStringLiteral("gradation");
const QString VAbstractPattern::TagHeights = QStringLiteral("heights");
const QString VAbstractPattern::TagSizes = QStringLiteral("sizes");
@ -1170,6 +1172,28 @@ void VAbstractPattern::InsertTag(const QStringList &tags, const QDomElement &ele
SetVersion();
}
//---------------------------------------------------------------------------------------------------------------------
int VAbstractPattern::GetIndexActivPP() const
{
const QDomNodeList drawList = elementsByTagName(TagDraw);
int index = 0;
if (not drawList.isEmpty())
{
for (int i = 0; i < drawList.size(); ++i)
{
QDomElement node = drawList.at(i).toElement();
if (node.attribute(AttrName) == nameActivPP)
{
index = i;
break;
}
}
}
return index;
}
//---------------------------------------------------------------------------------------------------------------------
QStringList VAbstractPattern::ListIncrements() const
{
@ -1201,6 +1225,7 @@ QStringList VAbstractPattern::ListExpressions() const
list << ListArcExpressions();
list << ListSplineExpressions();
list << ListIncrementExpressions();
list << ListOperationExpressions();
return list;
}
@ -1208,6 +1233,10 @@ QStringList VAbstractPattern::ListExpressions() const
//---------------------------------------------------------------------------------------------------------------------
QStringList VAbstractPattern::ListPointExpressions() const
{
// Check if new tool doesn't bring new attribute with a formula.
// If no just increment number
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 43);
QStringList expressions;
const QDomNodeList list = elementsByTagName(TagPoint);
for (int i=0; i < list.size(); ++i)
@ -1275,6 +1304,10 @@ QStringList VAbstractPattern::ListPointExpressions() const
//---------------------------------------------------------------------------------------------------------------------
QStringList VAbstractPattern::ListArcExpressions() const
{
// Check if new tool doesn't bring new attribute with a formula.
// If no just increment number
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 43);
QStringList expressions;
const QDomNodeList list = elementsByTagName(TagArc);
for (int i=0; i < list.size(); ++i)
@ -1332,6 +1365,10 @@ QStringList VAbstractPattern::ListSplineExpressions() const
//---------------------------------------------------------------------------------------------------------------------
QStringList VAbstractPattern::ListPathPointExpressions() const
{
// Check if new tool doesn't bring new attribute with a formula.
// If no just increment number
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 43);
QStringList expressions;
const QDomNodeList list = elementsByTagName(AttrPathPoint);
for (int i=0; i < list.size(); ++i)
@ -1391,6 +1428,33 @@ QStringList VAbstractPattern::ListIncrementExpressions() const
return expressions;
}
//---------------------------------------------------------------------------------------------------------------------
QStringList VAbstractPattern::ListOperationExpressions() const
{
// Check if new tool doesn't bring new attribute with a formula.
// If no just increment number
Q_STATIC_ASSERT(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 43);
QStringList expressions;
const QDomNodeList list = elementsByTagName(TagOperation);
for (int i=0; i < list.size(); ++i)
{
const QDomElement dom = list.at(i).toElement();
// Each tag can contains several attributes.
try
{
expressions.append(GetParametrString(dom, AttrAngle));
}
catch (VExceptionEmptyParameter &e)
{
Q_UNUSED(e)
}
}
return expressions;
}
//---------------------------------------------------------------------------------------------------------------------
bool VAbstractPattern::IsVariable(const QString &token) const
{

View file

@ -74,6 +74,7 @@ public:
virtual void DecrementReferens(quint32 id) const=0;
virtual QString GenerateLabel(const LabelType &type, const QString &reservedName = QString())const=0;
virtual QString GenerateSuffix() const=0;
virtual void UpdateToolData(const quint32 &id, VContainer *data)=0;
@ -132,6 +133,7 @@ public:
static const QString TagCalculation;
static const QString TagModeling;
static const QString TagDetails;
static const QString TagDetail;
static const QString TagAuthor;
static const QString TagDescription;
static const QString TagImage;
@ -148,6 +150,7 @@ public:
static const QString TagSpline;
static const QString TagArc;
static const QString TagTools;
static const QString TagOperation;
static const QString TagGradation;
static const QString TagHeights;
static const QString TagSizes;
@ -210,7 +213,7 @@ public:
signals:
/**
* @brief ChangedActivDraw change active pattern peace.
* @brief ChangedActivPP change active pattern peace.
* @param newName new pattern peace name.
*/
void ChangedActivPP(const QString &newName);
@ -282,6 +285,7 @@ protected:
QDomElement CheckTagExists(const QString &tag);
void InsertTag(const QStringList &tags, const QDomElement &element);
int GetIndexActivPP() const;
private:
Q_DISABLE_COPY(VAbstractPattern)
@ -292,6 +296,7 @@ private:
QStringList ListSplineExpressions() const;
QStringList ListPathPointExpressions() const;
QStringList ListIncrementExpressions() const;
QStringList ListOperationExpressions() const;
bool IsVariable(const QString& token) const;
bool IsPostfixOperator(const QString& token) const;

View file

@ -43,8 +43,8 @@
*/
const QString VPatternConverter::PatternMinVerStr = QStringLiteral("0.1.0");
const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.3.0");
const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.3.0.xsd");
const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.3.1");
const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.3.1.xsd");
//---------------------------------------------------------------------------------------------------------------------
VPatternConverter::VPatternConverter(const QString &fileName)
@ -111,8 +111,10 @@ QString VPatternConverter::XSDSchema(int ver) const
case (0x000206):
return QStringLiteral("://schema/pattern/v0.2.6.xsd");
case (0x000207):
return QStringLiteral("://schema/pattern/v0.3.0.xsd");
return QStringLiteral("://schema/pattern/v0.2.7.xsd");
case (0x000300):
return QStringLiteral("://schema/pattern/v0.3.0.xsd");
case (0x000301):
return CurrentSchema;
default:
InvalidVersion(ver);
@ -128,97 +130,62 @@ void VPatternConverter::ApplyPatches()
switch (ver)
{
case (0x000100):
{
ToV0_1_1();
const QString schema = XSDSchema(0x000101);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000101), fileName);
V_FALLTHROUGH
}
case (0x000101):
{
ToV0_1_2();
const QString schema = XSDSchema(0x000102);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000102), fileName);
V_FALLTHROUGH
}
case (0x000102):
{
ToV0_1_3();
const QString schema = XSDSchema(0x000103);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000103), fileName);
V_FALLTHROUGH
}
case (0x000103):
{
ToV0_1_4();
const QString schema = XSDSchema(0x000104);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000104), fileName);
V_FALLTHROUGH
}
case (0x000104):
{
ToV0_2_0();
const QString schema = XSDSchema(0x000200);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000200), fileName);
V_FALLTHROUGH
}
case (0x000200):
{
ToV0_2_1();
const QString schema = XSDSchema(0x000201);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000201), fileName);
V_FALLTHROUGH
}
case (0x000201):
{
ToV0_2_2();
const QString schema = XSDSchema(0x000202);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000202), fileName);
V_FALLTHROUGH
}
case (0x000202):
{
ToV0_2_3();
const QString schema = XSDSchema(0x000203);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000203), fileName);
V_FALLTHROUGH
}
case (0x000203):
{
ToV0_2_4();
const QString schema = XSDSchema(0x000204);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000204), fileName);
V_FALLTHROUGH
}
case (0x000204):
{
ToV0_2_5();
const QString schema = XSDSchema(0x000205);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000205), fileName);
V_FALLTHROUGH
}
case (0x000205):
{
ToV0_2_6();
const QString schema = XSDSchema(0x000206);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000206), fileName);
V_FALLTHROUGH
}
case (0x000206):
{
ToV0_2_7();
const QString schema = XSDSchema(0x000207);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000207), fileName);
V_FALLTHROUGH
}
case (0x000207):
{
ToV0_3_0();
const QString schema = XSDSchema(0x000300);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000300), fileName);
V_FALLTHROUGH
}
case (0x000300):
ToV0_3_1();
ValidateXML(XSDSchema(0x000301), fileName);
V_FALLTHROUGH
case (0x000301):
break;
default:
break;
@ -347,6 +314,14 @@ void VPatternConverter::ToV0_3_0()
Save();
}
//---------------------------------------------------------------------------------------------------------------------
void VPatternConverter::ToV0_3_1()
{
SetVersion(QStringLiteral("0.3.1"));
RemoveColorToolCutV0_3_1();
Save();
}
//---------------------------------------------------------------------------------------------------------------------
void VPatternConverter::TagUnitToV0_2_0()
{
@ -808,6 +783,26 @@ void VPatternConverter::ConvertMeasurementsToV0_2_1()
ConvertPathPointExpressionsToV0_2_0(names);
}
//---------------------------------------------------------------------------------------------------------------------
void VPatternConverter::RemoveColorToolCutV0_3_1()
{
const QDomNodeList list = elementsByTagName("point");
for (int i=0; i < list.size(); ++i)
{
QDomElement element = list.at(i).toElement();
if (not element.isNull())
{
const QString type = element.attribute(QStringLiteral("type"));
if (type == QStringLiteral("cutArc") ||
type == QStringLiteral("cutSpline") ||
type == QStringLiteral("cutSplinePath"))
{
element.removeAttribute(QStringLiteral("color"));
}
}
}
}
//---------------------------------------------------------------------------------------------------------------------
QString VPatternConverter::MUnitV0_1_4() const
{

View file

@ -69,6 +69,7 @@ private:
void ToV0_2_6();
void ToV0_2_7();
void ToV0_3_0();
void ToV0_3_1();
void TagUnitToV0_2_0();
void TagIncrementToV0_2_0();
@ -77,6 +78,8 @@ private:
void ConvertMeasurementsToV0_2_1();
void RemoveColorToolCutV0_3_1();
QSet<QString> FixIncrementsToV0_2_0();
QString FixIncrementInFormulaToV0_2_0(const QString &formula, const QSet<QString> &names);
void FixPointExpressionsToV0_2_0(const QSet<QString> &names);

View file

@ -107,33 +107,21 @@ void VVITConverter::ApplyPatches()
switch (ver)
{
case (0x000200):
{
ToV0_3_0();
const QString schema = XSDSchema(0x000300);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000300), fileName);
V_FALLTHROUGH
}
case (0x000300):
{
ToV0_3_1();
const QString schema = XSDSchema(0x000301);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000301), fileName);
V_FALLTHROUGH
}
case (0x000301):
{
ToV0_3_2();
const QString schema = XSDSchema(0x000302);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000302), fileName);
V_FALLTHROUGH
}
case (0x000302):
{
ToV0_3_3();
const QString schema = XSDSchema(0x000303);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000303), fileName);
V_FALLTHROUGH
}
case (0x000303):
break;
default:

View file

@ -105,26 +105,17 @@ void VVSTConverter::ApplyPatches()
switch (ver)
{
case (0x000300):
{
ToV0_4_0();
const QString schema = XSDSchema(0x000400);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000400), fileName);
V_FALLTHROUGH
}
case (0x000400):
{
ToV0_4_1();
const QString schema = XSDSchema(0x000401);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000401), fileName);
V_FALLTHROUGH
}
case (0x000401):
{
ToV0_4_2();
const QString schema = XSDSchema(0x000402);
ValidateXML(schema, fileName);
ValidateXML(XSDSchema(0x000402), fileName);
V_FALLTHROUGH
}
case (0x000402):
break;
default:

View file

@ -34,6 +34,7 @@
#include "../qmuparser/qmutokenparser.h"
#include <QDate>
#include <QtNumeric>
const QString VMeasurements::TagVST = QStringLiteral("vst");
const QString VMeasurements::TagVIT = QStringLiteral("vit");
@ -878,11 +879,10 @@ qreal VMeasurements::EvalFormula(VContainer *data, const QString &formula, bool
// Replace line return character with spaces for calc if exist
QString f = formula;
f.replace("\n", " ");
Calculator *cal = new Calculator();
QScopedPointer<Calculator> cal(new Calculator());
const qreal result = cal->EvalFormula(data->PlainVariables(), f);
delete cal;
*ok = true;
(qIsInf(result) || qIsNaN(result)) ? *ok = false : *ok = true;
return result;
}
catch (qmu::QmuParserError &e)

View file

@ -0,0 +1,208 @@
/************************************************************************
**
** @file vabstractarc.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 10 4, 2016
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2016 Valentina project
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "vabstractarc.h"
#include "vabstractarc_p.h"
//---------------------------------------------------------------------------------------------------------------------
VAbstractArc::VAbstractArc(const GOType &type, const quint32 &idObject, const Draw &mode)
: VAbstractCurve(type, idObject, mode), d (new VAbstractArcData())
{}
//---------------------------------------------------------------------------------------------------------------------
VAbstractArc::VAbstractArc(const GOType &type, const VPointF &center, qreal f1, const QString &formulaF1, qreal f2,
const QString &formulaF2, quint32 idObject, Draw mode)
: VAbstractCurve(type, idObject, mode), d (new VAbstractArcData(center, f1, formulaF1, f2, formulaF2))
{}
//---------------------------------------------------------------------------------------------------------------------
VAbstractArc::VAbstractArc(const GOType &type, const VPointF &center, qreal f1, qreal f2, quint32 idObject, Draw mode)
: VAbstractCurve(type, idObject, mode), d (new VAbstractArcData(center, f1, f2))
{}
//---------------------------------------------------------------------------------------------------------------------
VAbstractArc::VAbstractArc(const GOType &type, const QString &formulaLength, const VPointF &center,
qreal f1, const QString &formulaF1, quint32 idObject, Draw mode)
: VAbstractCurve(type, idObject, mode), d (new VAbstractArcData(formulaLength, center, f1, formulaF1))
{}
//---------------------------------------------------------------------------------------------------------------------
VAbstractArc::VAbstractArc(const GOType &type, const VPointF &center, qreal f1, quint32 idObject, Draw mode)
: VAbstractCurve(type, idObject, mode), d (new VAbstractArcData(center, f1))
{}
//---------------------------------------------------------------------------------------------------------------------
VAbstractArc::VAbstractArc(const VAbstractArc &arc)
: VAbstractCurve(arc), d (arc.d)
{}
//---------------------------------------------------------------------------------------------------------------------
VAbstractArc &VAbstractArc::operator=(const VAbstractArc &arc)
{
if ( &arc == this )
{
return *this;
}
VAbstractCurve::operator=(arc);
d = arc.d;
return *this;
}
//---------------------------------------------------------------------------------------------------------------------
VAbstractArc::~VAbstractArc()
{}
//---------------------------------------------------------------------------------------------------------------------
QString VAbstractArc::GetFormulaF1() const
{
return d->formulaF1;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractArc::SetFormulaF1(const QString &formula, qreal value)
{
d->formulaF1 = formula;
d->f1 = value;
}
//---------------------------------------------------------------------------------------------------------------------
qreal VAbstractArc::GetStartAngle() const
{
return d->f1;
}
//---------------------------------------------------------------------------------------------------------------------
QString VAbstractArc::GetFormulaF2() const
{
return d->formulaF2;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractArc::SetFormulaF2(const QString &formula, qreal value)
{
d->formulaF2 = formula;
d->f2 = value;
}
//---------------------------------------------------------------------------------------------------------------------
qreal VAbstractArc::GetEndAngle() const
{
return d->f2;
}
//---------------------------------------------------------------------------------------------------------------------
VPointF VAbstractArc::GetCenter() const
{
return d->center;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractArc::SetCenter(const VPointF &point)
{
d->center = point;
}
//---------------------------------------------------------------------------------------------------------------------
QString VAbstractArc::GetFormulaLength() const
{
return d->formulaLength;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractArc::SetFormulaLength(const QString &formula, qreal value)
{
d->formulaLength = formula;
FindF2(value);
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractArc::setId(const quint32 &id)
{
VAbstractCurve::setId(id);
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
QString VAbstractArc::NameForHistory(const QString &toolName) const
{
QString name = toolName + QString(" %1").arg(GetCenter().name());
if (VAbstractCurve::id() != NULL_ID)
{
name += QString("_%1").arg(VAbstractCurve::id());
}
if (GetDuplicate() > 0)
{
name += QString("_%1").arg(GetDuplicate());
}
return name;
}
//---------------------------------------------------------------------------------------------------------------------
bool VAbstractArc::IsFlipped() const
{
return d->isFlipped;
}
//---------------------------------------------------------------------------------------------------------------------
qreal VAbstractArc::AngleArc() const
{
{
const qreal angleDiff = qAbs(GetStartAngle() - GetEndAngle());
if (VFuzzyComparePossibleNulls(angleDiff, 0) || VFuzzyComparePossibleNulls(angleDiff, 360))
{
return 360;
}
}
QLineF l1(0, 0, 100, 0);
l1.setAngle(GetStartAngle());
QLineF l2(0, 0, 100, 0);
l2.setAngle(GetEndAngle());
qreal ang = l1.angleTo(l2);
if (IsFlipped())
{
ang = 360 - ang;
}
return ang;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractArc::SetFlipped(bool value)
{
d->isFlipped = value;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractArc::SetFormulaLength(const QString &formula)
{
d->formulaLength = formula;
}

View file

@ -0,0 +1,80 @@
/************************************************************************
**
** @file vabstractarc.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 10 4, 2016
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2016 Valentina project
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VABSTRACTARC_H
#define VABSTRACTARC_H
#include "vabstractcurve.h"
class VAbstractArcData;
class VPointF;
class VAbstractArc : public VAbstractCurve
{
public:
explicit VAbstractArc(const GOType &type, const quint32 &idObject = NULL_ID, const Draw &mode = Draw::Calculation);
VAbstractArc (const GOType &type, const VPointF &center, qreal f1, const QString &formulaF1, qreal f2,
const QString &formulaF2, quint32 idObject = 0, Draw mode = Draw::Calculation);
VAbstractArc (const GOType &type, const VPointF &center, qreal f1, qreal f2, quint32 idObject = 0,
Draw mode = Draw::Calculation);
VAbstractArc (const GOType &type, const QString &formulaLength, const VPointF &center, qreal f1,
const QString &formulaF1, quint32 idObject = 0, Draw mode = Draw::Calculation);
VAbstractArc (const GOType &type, const VPointF &center, qreal f1, quint32 idObject = 0,
Draw mode = Draw::Calculation);
explicit VAbstractArc(const VAbstractArc &arc);
VAbstractArc& operator= (const VAbstractArc &arc);
virtual ~VAbstractArc();
QString GetFormulaF1 () const;
void SetFormulaF1 (const QString &formula, qreal value);
virtual qreal GetStartAngle () const Q_DECL_OVERRIDE;
QString GetFormulaF2 () const;
void SetFormulaF2 (const QString &formula, qreal value);
virtual qreal GetEndAngle () const Q_DECL_OVERRIDE;
VPointF GetCenter () const;
void SetCenter (const VPointF &point);
QString GetFormulaLength () const;
void SetFormulaLength (const QString &formula, qreal value);
virtual void setId(const quint32 &id) Q_DECL_OVERRIDE;
virtual QString NameForHistory(const QString &toolName) const Q_DECL_OVERRIDE;
bool IsFlipped() const;
qreal AngleArc() const;
protected:
void SetFlipped(bool value);
virtual void FindF2(qreal length)=0;
void SetFormulaLength(const QString &formula);
private:
QSharedDataPointer<VAbstractArcData> d;
};
#endif // VABSTRACTARC_H

View file

@ -0,0 +1,148 @@
/************************************************************************
**
** @file VAbstractArcData.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 10 4, 2016
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2016 Valentina project
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VABSTRACTARC_P_H
#define VABSTRACTARC_P_H
#include <QSharedData>
#include "vgeometrydef.h"
#include "../vmisc/vabstractapplication.h"
#include "vpointf.h"
#ifdef Q_CC_GNU
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#endif
class VAbstractArcData : public QSharedData
{
public:
VAbstractArcData();
VAbstractArcData(const VPointF &center, qreal f1, const QString &formulaF1, qreal f2, const QString &formulaF2);
VAbstractArcData(const QString &formulaLength, VPointF center, qreal f1, QString formulaF1);
VAbstractArcData(const VPointF &center, qreal f1);
VAbstractArcData(const VPointF &center, qreal f1, qreal f2);
VAbstractArcData(const VAbstractArcData &arc);
virtual ~VAbstractArcData();
/** @brief f1 start angle in degree. */
qreal f1;
/** @brief formulaF1 formula for start angle. */
QString formulaF1;
/** @brief f2 end angle in degree. */
qreal f2;
/** @brief formulaF2 formula for end angle. */
QString formulaF2;
/** @brief center center point of arc. */
VPointF center;
bool isFlipped;
QString formulaLength;
private:
VAbstractArcData &operator=(const VAbstractArcData &) Q_DECL_EQ_DELETE;
};
//---------------------------------------------------------------------------------------------------------------------
VAbstractArcData::VAbstractArcData()
: f1(0),
formulaF1(),
f2(0),
formulaF2(),
center(),
isFlipped(false),
formulaLength()
{}
//---------------------------------------------------------------------------------------------------------------------
VAbstractArcData::VAbstractArcData(const VPointF &center, qreal f1, const QString &formulaF1, qreal f2,
const QString &formulaF2)
: f1(f1),
formulaF1(formulaF1),
f2(f2),
formulaF2(formulaF2),
center(center),
isFlipped(false),
formulaLength()
{}
//---------------------------------------------------------------------------------------------------------------------
VAbstractArcData::VAbstractArcData(const QString &formulaLength, VPointF center, qreal f1, QString formulaF1)
: f1(f1),
formulaF1(formulaF1),
f2(0),
formulaF2("0"),
center(center),
isFlipped(false),
formulaLength(formulaLength)
{}
//---------------------------------------------------------------------------------------------------------------------
VAbstractArcData::VAbstractArcData(const VPointF &center, qreal f1)
: f1(f1),
formulaF1(QString().number(f1)),
f2(0),
formulaF2("0"),
center(center),
isFlipped(false),
formulaLength()
{}
//---------------------------------------------------------------------------------------------------------------------
VAbstractArcData::VAbstractArcData(const VPointF &center, qreal f1, qreal f2)
: f1(f1),
formulaF1(QString().number(f1)),
f2(f2),
formulaF2(QString().number(f2)),
center(center),
isFlipped(false),
formulaLength()
{}
//---------------------------------------------------------------------------------------------------------------------
VAbstractArcData::VAbstractArcData(const VAbstractArcData &arc)
: QSharedData(arc),
f1(arc.f1),
formulaF1(arc.formulaF1),
f2(arc.f2),
formulaF2(arc.formulaF2),
center(arc.center),
isFlipped(arc.isFlipped),
formulaLength(arc.formulaLength)
{}
//---------------------------------------------------------------------------------------------------------------------
VAbstractArcData::~VAbstractArcData()
{}
#endif // VABSTRACTARCDATA_H

View file

@ -97,7 +97,7 @@ QPointF VAbstractCubicBezier::CutSpline(qreal length, QPointF &spl1p2, QPointF &
const qreal parT = GetParmT(length);
QLineF seg1_2 ( GetP1 ().toQPointF(), GetControlPoint1 () );
QLineF seg1_2 ( GetP1 (), GetControlPoint1 () );
seg1_2.setLength(seg1_2.length () * parT);
const QPointF p12 = seg1_2.p2();
@ -109,7 +109,7 @@ QPointF VAbstractCubicBezier::CutSpline(qreal length, QPointF &spl1p2, QPointF &
seg12_23.setLength(seg12_23.length () * parT);
const QPointF p123 = seg12_23.p2();
QLineF seg3_4 ( GetControlPoint2 (), GetP4 ().toQPointF() );
QLineF seg3_4 ( GetControlPoint2 (), GetP4 () );
seg3_4.setLength(seg3_4.length () * parT);
const QPointF p34 = seg3_4.p2();
@ -547,7 +547,7 @@ qreal VAbstractCubicBezier::LengthT(qreal t) const
qDebug()<<"Wrong value t.";
return 0;
}
QLineF seg1_2 ( GetP1 ().toQPointF(), GetControlPoint1 () );
QLineF seg1_2 ( GetP1 (), GetControlPoint1 () );
seg1_2.setLength(seg1_2.length () * t);
const QPointF p12 = seg1_2.p2();
@ -559,7 +559,7 @@ qreal VAbstractCubicBezier::LengthT(qreal t) const
seg12_23.setLength(seg12_23.length () * t);
const QPointF p123 = seg12_23.p2();
QLineF seg3_4 ( GetControlPoint2 (), GetP4 ().toQPointF() );
QLineF seg3_4 ( GetControlPoint2 (), GetP4 () );
seg3_4.setLength(seg3_4.length () * t);
const QPointF p34 = seg3_4.p2();
@ -571,5 +571,5 @@ qreal VAbstractCubicBezier::LengthT(qreal t) const
seg123_234.setLength(seg123_234.length () * t);
const QPointF p1234 = seg123_234.p2();
return LengthBezier ( GetP1().toQPointF(), p12, p123, p1234);
return LengthBezier ( GetP1(), p12, p123, p1234);
}

View file

@ -244,6 +244,18 @@ void VAbstractCurve::SetDuplicate(quint32 number)
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
QString VAbstractCurve::GetColor() const
{
return d->color;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractCurve::SetColor(const QString &color)
{
d->color = color;
}
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VAbstractCurve::CurveIntersectLine(const QVector<QPointF> &points, const QLineF &line)
{

View file

@ -69,6 +69,9 @@ public:
quint32 GetDuplicate() const;
void SetDuplicate(quint32 number);
QString GetColor() const;
void SetColor(const QString &color);
static QVector<QPointF> CurveIntersectLine(const QVector<QPointF> &points, const QLineF &line);
virtual QString NameForHistory(const QString &toolName) const=0;

View file

@ -31,6 +31,8 @@
#include <QSharedData>
#include "../ifc/ifcdef.h"
#ifdef Q_CC_GNU
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
@ -41,11 +43,11 @@ class VAbstractCurveData : public QSharedData
public:
VAbstractCurveData ()
: duplicate(0)
: duplicate(0), color(ColorBlack)
{}
VAbstractCurveData(const VAbstractCurveData &curve)
: QSharedData(curve), duplicate(curve.duplicate)
: QSharedData(curve), duplicate(curve.duplicate), color(curve.color)
{}
virtual ~VAbstractCurveData();
@ -53,6 +55,8 @@ public:
/** @brief duplicate helps create unique name for curves that connects the same start and finish points. */
quint32 duplicate;
QString color;
private:
VAbstractCurveData &operator=(const VAbstractCurveData &) Q_DECL_EQ_DELETE;
};

View file

@ -42,7 +42,8 @@
* @brief VArc default constructor.
*/
VArc::VArc ()
:VAbstractCurve(GOType::Arc), d (new VArcData)
: VAbstractArc(GOType::Arc),
d (new VArcData)
{}
//---------------------------------------------------------------------------------------------------------------------
@ -53,34 +54,36 @@ VArc::VArc ()
* @param f1 start angle (degree).
* @param f2 end angle (degree).
*/
VArc::VArc (VPointF center, qreal radius, QString formulaRadius, qreal f1, QString formulaF1, qreal f2,
QString formulaF2, quint32 idObject, Draw mode)
: VAbstractCurve(GOType::Arc, idObject, mode),
d (new VArcData(center, radius, formulaRadius, f1, formulaF1, f2, formulaF2))
VArc::VArc (const VPointF &center, qreal radius, const QString &formulaRadius, qreal f1, const QString &formulaF1,
qreal f2, const QString &formulaF2, quint32 idObject, Draw mode)
: VAbstractArc(GOType::Arc, center, f1, formulaF1, f2, formulaF2, idObject, mode),
d (new VArcData(radius, formulaRadius))
{
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
VArc::VArc(VPointF center, qreal radius, qreal f1, qreal f2)
: VAbstractCurve(GOType::Arc, NULL_ID, Draw::Calculation), d (new VArcData(center, radius, f1, f2))
VArc::VArc(const VPointF &center, qreal radius, qreal f1, qreal f2)
: VAbstractArc(GOType::Arc, center, f1, f2, NULL_ID, Draw::Calculation),
d (new VArcData(radius))
{
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
VArc::VArc(qreal length, QString formulaLength, VPointF center, qreal radius, QString formulaRadius, qreal f1,
QString formulaF1, quint32 idObject, Draw mode)
: VAbstractCurve(GOType::Arc, idObject, mode),
d (new VArcData(formulaLength, center, radius, formulaRadius, f1, formulaF1))
VArc::VArc(qreal length, const QString &formulaLength, const VPointF &center, qreal radius,
const QString &formulaRadius, qreal f1, const QString &formulaF1, quint32 idObject, Draw mode)
: VAbstractArc(GOType::Arc, formulaLength, center, f1, formulaF1, idObject, mode),
d (new VArcData(radius, formulaRadius))
{
CreateName();
FindF2(length);
}
//---------------------------------------------------------------------------------------------------------------------
VArc::VArc(qreal length, VPointF center, qreal radius, qreal f1)
: VAbstractCurve(GOType::Arc, NULL_ID, Draw::Calculation), d (new VArcData(center, radius, f1))
VArc::VArc(qreal length, const VPointF &center, qreal radius, qreal f1)
: VAbstractArc(GOType::Arc, center, f1, NULL_ID, Draw::Calculation),
d (new VArcData(radius))
{
CreateName();
FindF2(length);
@ -92,7 +95,7 @@ VArc::VArc(qreal length, VPointF center, qreal radius, qreal f1)
* @param arc arc
*/
VArc::VArc(const VArc &arc)
: VAbstractCurve(arc), d (arc.d)
: VAbstractArc(arc), d (arc.d)
{}
//---------------------------------------------------------------------------------------------------------------------
@ -107,11 +110,24 @@ VArc &VArc::operator =(const VArc &arc)
{
return *this;
}
VAbstractCurve::operator=(arc);
VAbstractArc::operator=(arc);
d = arc.d;
return *this;
}
//---------------------------------------------------------------------------------------------------------------------
VArc VArc::Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix) const
{
const VPointF center = GetCenter().Rotate(originPoint, degrees);
const QPointF p1 = VPointF::RotatePF(originPoint, GetP1(), degrees);
const QPointF p2 = VPointF::RotatePF(originPoint, GetP2(), degrees);
VArc arc(center, GetRadius(), QLineF(center, p1).angle(), QLineF(center, p2).angle());
arc.setName(name() + prefix);
return arc;
}
//---------------------------------------------------------------------------------------------------------------------
VArc::~VArc()
{}
@ -124,7 +140,7 @@ VArc::~VArc()
qreal VArc::GetLength() const
{
qreal length = d->radius * qDegreesToRadians(AngleArc());
if (d->isFlipped)
if (IsFlipped())
{
length *= -1;
}
@ -140,8 +156,8 @@ qreal VArc::GetLength() const
QPointF VArc::GetP1() const
{
QPointF p1 ( GetCenter().x () + d->radius, GetCenter().y () );
QLineF centerP1(GetCenter().toQPointF(), p1);
centerP1.setAngle(d->f1);
QLineF centerP1(GetCenter(), p1);
centerP1.setAngle(GetStartAngle());
return centerP1.p2();
}
@ -153,40 +169,11 @@ QPointF VArc::GetP1() const
QPointF VArc::GetP2 () const
{
QPointF p2 ( GetCenter().x () + d->radius, GetCenter().y () );
QLineF centerP2(GetCenter().toQPointF(), p2);
centerP2.setAngle(d->f2);
QLineF centerP2(GetCenter(), p2);
centerP2.setAngle(GetEndAngle());
return centerP2.p2();
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief AngleArc calculate arc angle.
* @return angle in degree.
*/
qreal VArc::AngleArc() const
{
{
const qreal angleDiff = qAbs(d->f1 - d->f2);
if (VFuzzyComparePossibleNulls(angleDiff, 0) || VFuzzyComparePossibleNulls(angleDiff, 360))
{
return 360;
}
}
QLineF l1(0, 0, 100, 0);
l1.setAngle(d->f1);
QLineF l2(0, 0, 100, 0);
l2.setAngle(d->f2);
qreal ang = l1.angleTo(l2);
if (d->isFlipped)
{
ang = 360 - ang;
}
return ang;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetPoints return list of points needed for drawing arc.
@ -198,7 +185,7 @@ QVector<QPointF> VArc::GetPoints() const
QVector<qreal> sectionAngle;
QPointF pStart;
d->isFlipped ? pStart = GetP2() : pStart = GetP1();
IsFlipped() ? pStart = GetP2() : pStart = GetP1();
{
qreal angle = AngleArc();
@ -234,7 +221,7 @@ QVector<QPointF> VArc::GetPoints() const
{
const qreal lDistance = GetRadius() * 4.0/3.0 * qTan(qDegreesToRadians(sectionAngle.at(i)) * 0.25);
const QPointF center = GetCenter().toQPointF();
const QPointF center = GetCenter();
QLineF lineP1P2(pStart, center);
lineP1P2.setAngle(lineP1P2.angle() - 90.0);
@ -299,14 +286,14 @@ QPointF VArc::CutArc(const qreal &length, VArc &arc1, VArc &arc2) const
qreal n = qRadiansToDegrees(len/d->radius); // n - is angle in degrees
QLineF line(GetCenter().toQPointF(), GetP1());
QLineF line(GetCenter(), GetP1());
line.setAngle(line.angle()+n);
arc1 = VArc (d->center, d->radius, d->formulaRadius, d->f1, d->formulaF1, line.angle(),
arc1 = VArc (GetCenter(), d->radius, d->formulaRadius, GetStartAngle(), GetFormulaF1(), line.angle(),
QString().setNum(line.angle()), getIdObject(), getMode());
arc2 = VArc (d->center, d->radius, d->formulaRadius, line.angle(), QString().setNum(line.angle()), d->f2,
d->formulaF2, getIdObject(), getMode());
arc2 = VArc (GetCenter(), d->radius, d->formulaRadius, line.angle(), QString().setNum(line.angle()), GetEndAngle(),
GetFormulaF2(), getIdObject(), getMode());
return line.p2();
}
@ -319,34 +306,6 @@ QPointF VArc::CutArc(const qreal &length) const
return this->CutArc(length, arc1, arc2);
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief setId keep id arc in data.
* @param id id arc in data.
*/
void VArc::setId(const quint32 &id)
{
VAbstractCurve::setId(id);
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
QString VArc::NameForHistory(const QString &toolName) const
{
QString name = toolName + QString(" %1").arg(this->GetCenter().name());
if (VAbstractCurve::id() != NULL_ID)
{
name += QString("_%1").arg(VAbstractCurve::id());
}
if (GetDuplicate() > 0)
{
name += QString("_%1").arg(GetDuplicate());
}
return name;
}
//---------------------------------------------------------------------------------------------------------------------
void VArc::CreateName()
{
@ -368,7 +327,7 @@ void VArc::CreateName()
//---------------------------------------------------------------------------------------------------------------------
void VArc::FindF2(qreal length)
{
length < 0 ? d->isFlipped = true : d->isFlipped = false;
SetFlipped(length < 0);
if (length >= MaxLength())
{
@ -377,16 +336,15 @@ void VArc::FindF2(qreal length)
qreal arcAngle = qAbs(qRadiansToDegrees(length/d->radius));
if (d->isFlipped)
if (IsFlipped())
{
arcAngle = arcAngle * -1;
}
QLineF startAngle(0, 0, 100, 0);
startAngle.setAngle(d->f1 + arcAngle);// We use QLineF just because it is easy way correct angle value
startAngle.setAngle(GetStartAngle() + arcAngle);// We use QLineF just because it is easy way correct angle value
d->f2 = startAngle.angle();
d->formulaF2 = QString().number(d->f2);
SetFormulaF2(QString().number(startAngle.angle()), startAngle.angle());
}
//---------------------------------------------------------------------------------------------------------------------
@ -395,60 +353,6 @@ qreal VArc::MaxLength() const
return M_2PI*d->radius;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetF1 return start angle.
* @return angle in degree.
*/
QString VArc::GetFormulaF1() const
{
return d->formulaF1;
}
//---------------------------------------------------------------------------------------------------------------------
void VArc::SetFormulaF1(const QString &formula, qreal value)
{
d->formulaF1 = formula;
d->f1 = value;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetF1 return formula for start angle.
* @return string with formula.
*/
qreal VArc::GetStartAngle() const
{
return d->f1;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetF2 return end angle.
* @return angle in degree.
*/
QString VArc::GetFormulaF2() const
{
return d->formulaF2;
}
//---------------------------------------------------------------------------------------------------------------------
void VArc::SetFormulaF2(const QString &formula, qreal value)
{
d->formulaF2 = formula;
d->f2 = value;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetF2 return formula for end angle.
* @return string with formula.
*/
qreal VArc::GetEndAngle() const
{
return d->f2;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetRadius return arc radius.
@ -475,32 +379,3 @@ qreal VArc::GetRadius() const
{
return d->radius;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetCenter return center point.
* @return center point.
*/
VPointF VArc::GetCenter() const
{
return d->center;
}
//---------------------------------------------------------------------------------------------------------------------
void VArc::SetCenter(const VPointF &value)
{
d->center = value;
}
//---------------------------------------------------------------------------------------------------------------------
QString VArc::GetFormulaLength() const
{
return d->formulaLength;
}
//---------------------------------------------------------------------------------------------------------------------
void VArc::SetFormulaLength(const QString &formula, qreal value)
{
d->formulaLength = formula;
FindF2(value);
}

View file

@ -29,7 +29,7 @@
#ifndef VARC_H
#define VARC_H
#include "vabstractcurve.h"
#include "vabstractarc.h"
#include "vpointf.h"
#include <QCoreApplication>
@ -39,55 +39,41 @@ class VArcData;
/**
* @brief VArc class for anticlockwise arc.
*/
class VArc: public VAbstractCurve
class VArc: public VAbstractArc
{
Q_DECLARE_TR_FUNCTIONS(VArc)
public:
VArc ();
VArc (VPointF center, qreal radius, QString formulaRadius, qreal f1, QString formulaF1, qreal f2,
QString formulaF2, quint32 idObject = 0, Draw mode = Draw::Calculation);
VArc (VPointF center, qreal radius, qreal f1, qreal f2);
VArc (qreal length, QString formulaLength, VPointF center, qreal radius, QString formulaRadius, qreal f1,
QString formulaF1, quint32 idObject = 0, Draw mode = Draw::Calculation);
VArc (qreal length, VPointF center, qreal radius, qreal f1);
VArc (const VPointF &center, qreal radius, const QString &formulaRadius, qreal f1, const QString &formulaF1,
qreal f2, const QString &formulaF2, quint32 idObject = 0, Draw mode = Draw::Calculation);
VArc (const VPointF &center, qreal radius, qreal f1, qreal f2);
VArc (qreal length, const QString &formulaLength, const VPointF &center, qreal radius, const QString &formulaRadius,
qreal f1, const QString &formulaF1, quint32 idObject = 0, Draw mode = Draw::Calculation);
VArc (qreal length, const VPointF &center, qreal radius, qreal f1);
VArc(const VArc &arc);
VArc& operator= (const VArc &arc);
VArc Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix = QString()) const;
virtual ~VArc() Q_DECL_OVERRIDE;
QString GetFormulaF1 () const;
void SetFormulaF1 (const QString &formula, qreal value);
virtual qreal GetStartAngle () const Q_DECL_OVERRIDE;
QString GetFormulaRadius () const;
void SetFormulaRadius (const QString &formula, qreal value);
qreal GetRadius () const;
QString GetFormulaF2 () const;
void SetFormulaF2 (const QString &formula, qreal value);
virtual qreal GetEndAngle () const Q_DECL_OVERRIDE;
virtual qreal GetLength () const Q_DECL_OVERRIDE;
QString GetFormulaRadius () const;
void SetFormulaRadius (const QString &formula, qreal value);
qreal GetRadius () const;
QPointF GetP1() const;
QPointF GetP2 () const;
VPointF GetCenter () const;
void SetCenter (const VPointF &value);
QString GetFormulaLength () const;
void SetFormulaLength (const QString &formula, qreal value);
virtual qreal GetLength () const Q_DECL_OVERRIDE;
QPointF GetP1() const;
QPointF GetP2 () const;
qreal AngleArc() const;
virtual QVector<QPointF> GetPoints () const Q_DECL_OVERRIDE;
QPointF CutArc (const qreal &length, VArc &arc1, VArc &arc2) const;
QPointF CutArc (const qreal &length) const;
virtual void setId(const quint32 &id) Q_DECL_OVERRIDE;
virtual QString NameForHistory(const QString &toolName) const Q_DECL_OVERRIDE;
QPointF CutArc (const qreal &length, VArc &arc1, VArc &arc2) const;
QPointF CutArc (const qreal &length) const;
protected:
virtual void CreateName() Q_DECL_OVERRIDE;
virtual void FindF2(qreal length) Q_DECL_OVERRIDE;
private:
QSharedDataPointer<VArcData> d;
void FindF2(qreal length);
qreal MaxLength() const;
};

View file

@ -32,7 +32,6 @@
#include <QSharedData>
#include "vgeometrydef.h"
#include "../vmisc/vabstractapplication.h"
#include "vpointf.h"
#ifdef Q_CC_GNU
#pragma GCC diagnostic push
@ -42,72 +41,48 @@
class VArcData : public QSharedData
{
public:
VArcData ()
: f1(0), formulaF1(QString()), f2(0), formulaF2(QString()), radius(0), formulaRadius(QString()),
center(VPointF()), isFlipped(false), formulaLength()
{}
VArcData (VPointF center, qreal radius, QString formulaRadius, qreal f1, QString formulaF1, qreal f2,
QString formulaF2)
: f1(f1), formulaF1(formulaF1), f2(f2), formulaF2(formulaF2), radius(radius), formulaRadius(formulaRadius),
center(center), isFlipped(false), formulaLength()
{}
VArcData(VPointF center, qreal radius, qreal f1, qreal f2)
: f1(f1), formulaF1(QString().number(f1)),
f2(f2), formulaF2(QString().number(f2)),
radius(radius), formulaRadius(QString().number(qApp->fromPixel(radius))),
center(center), isFlipped(false), formulaLength()
{}
VArcData (QString formulaLength, VPointF center, qreal radius, QString formulaRadius, qreal f1, QString formulaF1)
: f1(f1), formulaF1(formulaF1), f2(0), formulaF2("0"), radius(radius), formulaRadius(formulaRadius),
center(center), isFlipped(false), formulaLength(formulaLength)
{}
VArcData(VPointF center, qreal radius, qreal f1)
: f1(f1), formulaF1(QString().number(f1)), f2(0), formulaF2("0"), radius(radius),
formulaRadius(QString().number(qApp->fromPixel(radius))), center(center), isFlipped(false), formulaLength()
{}
VArcData(const VArcData &arc)
: QSharedData(arc), f1(arc.f1), formulaF1(arc.formulaF1), f2(arc.f2), formulaF2(arc.formulaF2),
radius(arc.radius), formulaRadius(arc.formulaRadius), center(arc.center), isFlipped(arc.isFlipped),
formulaLength(arc.formulaLength)
{}
VArcData();
VArcData(qreal radius, QString formulaRadius);
VArcData(qreal radius);
VArcData(const VArcData &arc);
virtual ~VArcData();
/** @brief f1 start angle in degree. */
qreal f1;
/** @brief formulaF1 formula for start angle. */
QString formulaF1;
/** @brief f2 end angle in degree. */
qreal f2;
/** @brief formulaF2 formula for end angle. */
QString formulaF2;
/** @brief radius arc radius. */
qreal radius;
/** @brief formulaRadius formula for arc radius. */
QString formulaRadius;
/** @brief center center point of arc. */
VPointF center;
bool isFlipped;
QString formulaLength;
private:
VArcData &operator=(const VArcData &) Q_DECL_EQ_DELETE;
};
//---------------------------------------------------------------------------------------------------------------------
VArcData::VArcData()
: radius(0),
formulaRadius(QString())
{}
//---------------------------------------------------------------------------------------------------------------------
VArcData::VArcData(qreal radius, QString formulaRadius)
: radius(radius),
formulaRadius(formulaRadius)
{}
//---------------------------------------------------------------------------------------------------------------------
VArcData::VArcData(qreal radius)
: radius(radius),
formulaRadius(QString().number(qApp->fromPixel(radius)))
{}
//---------------------------------------------------------------------------------------------------------------------
VArcData::VArcData(const VArcData &arc)
: QSharedData(arc),
radius(arc.radius),
formulaRadius(arc.formulaRadius)
{}
//---------------------------------------------------------------------------------------------------------------------
VArcData::~VArcData()
{}

View file

@ -61,6 +61,18 @@ VCubicBezier &VCubicBezier::operator=(const VCubicBezier &curve)
return *this;
}
//---------------------------------------------------------------------------------------------------------------------
VCubicBezier VCubicBezier::Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix) const
{
const VPointF p1 = GetP1().Rotate(originPoint, degrees);
const VPointF p2 = GetP2().Rotate(originPoint, degrees);
const VPointF p3 = GetP3().Rotate(originPoint, degrees);
const VPointF p4 = GetP4().Rotate(originPoint, degrees);
VCubicBezier curve(p1, p2, p3, p4);
curve.setName(name() + prefix);
return curve;
}
//---------------------------------------------------------------------------------------------------------------------
VCubicBezier::~VCubicBezier()
{
@ -117,13 +129,13 @@ void VCubicBezier::SetP4(const VPointF &p)
//---------------------------------------------------------------------------------------------------------------------
qreal VCubicBezier::GetStartAngle() const
{
return QLineF(GetP1().toQPointF(), GetP2().toQPointF()).angle();
return QLineF(GetP1(), GetP2()).angle();
}
//---------------------------------------------------------------------------------------------------------------------
qreal VCubicBezier::GetEndAngle() const
{
return QLineF(GetP4().toQPointF(), GetP3().toQPointF()).angle();
return QLineF(GetP4(), GetP3()).angle();
}
//---------------------------------------------------------------------------------------------------------------------
@ -133,7 +145,7 @@ qreal VCubicBezier::GetEndAngle() const
*/
qreal VCubicBezier::GetLength() const
{
return LengthBezier (GetP1().toQPointF(), GetP2().toQPointF(), GetP3().toQPointF(), GetP4().toQPointF());
return LengthBezier (GetP1(), GetP2(), GetP3(), GetP4());
}
//---------------------------------------------------------------------------------------------------------------------
@ -143,17 +155,17 @@ qreal VCubicBezier::GetLength() const
*/
QVector<QPointF> VCubicBezier::GetPoints() const
{
return GetCubicBezierPoints(GetP1().toQPointF(), GetP2().toQPointF(), GetP3().toQPointF(), GetP4().toQPointF());
return GetCubicBezierPoints(GetP1(), GetP2(), GetP3(), GetP4());
}
//---------------------------------------------------------------------------------------------------------------------
QPointF VCubicBezier::GetControlPoint1() const
{
return GetP2().toQPointF();
return GetP2();
}
//---------------------------------------------------------------------------------------------------------------------
QPointF VCubicBezier::GetControlPoint2() const
{
return GetP3().toQPointF();
return GetP3();
}

View file

@ -42,6 +42,7 @@ public:
VCubicBezier(const VPointF &p1, const VPointF &p2, const VPointF &p3, const VPointF &p4, quint32 idObject = 0,
Draw mode = Draw::Calculation);
VCubicBezier &operator=(const VCubicBezier &curve);
VCubicBezier Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix = QString()) const;
virtual ~VCubicBezier();
virtual VPointF GetP1() const Q_DECL_OVERRIDE;

View file

@ -79,6 +79,19 @@ VCubicBezierPath &VCubicBezierPath::operator=(const VCubicBezierPath &curve)
return *this;
}
//---------------------------------------------------------------------------------------------------------------------
VCubicBezierPath VCubicBezierPath::Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix) const
{
const QVector<VPointF> points = GetCubicPath();
VCubicBezierPath curve;
for(int i=0; i < points.size(); ++i)
{
curve.append(points.at(i).Rotate(originPoint, degrees));
}
curve.setName(name() + prefix);
return curve;
}
//---------------------------------------------------------------------------------------------------------------------
VCubicBezierPath::~VCubicBezierPath()
{
@ -99,7 +112,7 @@ const VPointF &VCubicBezierPath::at(int indx) const
//---------------------------------------------------------------------------------------------------------------------
void VCubicBezierPath::append(const VPointF &point)
{
if (d->path.size() > 0 && d->path.last().toQPointF() != point.toQPointF())
if (d->path.size() > 0 && d->path.last() != point)
{
return;
}
@ -143,18 +156,18 @@ VSpline VCubicBezierPath::GetSpline(qint32 index) const
const qint32 base = SubSplOffset(index);
// Correction the first control point of each next spline curve except for the first.
QPointF p2 = d->path.at(base + 1).toQPointF();
QPointF p2 = d->path.at(base + 1);
if (base + 1 > 1)
{
const QPointF b = d->path.at(base).toQPointF();
QLineF foot1(b, d->path.at(base - 1).toQPointF());
const QPointF b = d->path.at(base);
QLineF foot1(b, d->path.at(base - 1));
QLineF foot2(b, p2);
foot2.setAngle(foot1.angle() + 180);
p2 = foot2.p2();
}
VSpline spl(d->path.at(base), p2, d->path.at(base + 2).toQPointF(), d->path.at(base + 3));
VSpline spl(d->path.at(base), p2, d->path.at(base + 2), d->path.at(base + 3));
return spl;
}

View file

@ -45,6 +45,7 @@ public:
VCubicBezierPath(const VCubicBezierPath &curve);
VCubicBezierPath(const QVector<VPointF> &points, quint32 idObject = 0, Draw mode = Draw::Calculation);
VCubicBezierPath &operator=(const VCubicBezierPath &curve);
VCubicBezierPath Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix = QString()) const;
virtual ~VCubicBezierPath();
VPointF &operator[](int indx);

View file

@ -39,7 +39,7 @@
* @brief VEllipticalArc default constructor.
*/
VEllipticalArc::VEllipticalArc()
:VAbstractCurve(GOType::EllipticalArc), d (new VEllipticalArcData)
: VAbstractArc(GOType::EllipticalArc), d (new VEllipticalArcData)
{}
//---------------------------------------------------------------------------------------------------------------------
@ -51,41 +51,40 @@ VEllipticalArc::VEllipticalArc()
* @param f1 start angle (degree).
* @param f2 end angle (degree).
*/
VEllipticalArc::VEllipticalArc (VPointF center, qreal radius1, qreal radius2,
QString formulaRadius1, QString formulaRadius2, qreal f1, QString formulaF1, qreal f2,
QString formulaF2, qreal rotationAngle, quint32 idObject, Draw mode)
: VAbstractCurve(GOType::EllipticalArc, idObject, mode),
d (new VEllipticalArcData(center, radius1, radius2, formulaRadius1, formulaRadius2,
f1, formulaF1, f2, formulaF2, rotationAngle))
VEllipticalArc::VEllipticalArc (const VPointF &center, qreal radius1, qreal radius2, const QString &formulaRadius1,
const QString &formulaRadius2, qreal f1, const QString &formulaF1, qreal f2,
const QString &formulaF2, qreal rotationAngle, quint32 idObject, Draw mode)
: VAbstractArc(GOType::EllipticalArc, center, f1, formulaF1, f2, formulaF2, idObject, mode),
d (new VEllipticalArcData(radius1, radius2, formulaRadius1, formulaRadius2, rotationAngle))
{
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
VEllipticalArc::VEllipticalArc(VPointF center, qreal radius1, qreal radius2, qreal f1, qreal f2, qreal rotationAngle)
: VAbstractCurve(GOType::EllipticalArc, NULL_ID, Draw::Calculation),
d (new VEllipticalArcData(center, radius1, radius2, f1, f2, rotationAngle))
VEllipticalArc::VEllipticalArc(const VPointF &center, qreal radius1, qreal radius2, qreal f1, qreal f2,
qreal rotationAngle)
: VAbstractArc(GOType::EllipticalArc, center, f1, f2, NULL_ID, Draw::Calculation),
d (new VEllipticalArcData(radius1, radius2, rotationAngle))
{
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
VEllipticalArc::VEllipticalArc(qreal length, QString formulaLength, VPointF center, qreal radius1, qreal radius2,
QString formulaRadius1, QString formulaRadius2, qreal f1, QString formulaF1, qreal rotationAngle,
quint32 idObject, Draw mode)
: VAbstractCurve(GOType::EllipticalArc, idObject, mode),
d (new VEllipticalArcData(formulaLength, center, radius1, radius2, formulaRadius1, formulaRadius2,
f1, formulaF1, rotationAngle))
VEllipticalArc::VEllipticalArc(qreal length, const QString &formulaLength, const VPointF &center, qreal radius1,
qreal radius2, const QString &formulaRadius1, const QString &formulaRadius2, qreal f1,
const QString &formulaF1, qreal rotationAngle, quint32 idObject, Draw mode)
: VAbstractArc(GOType::EllipticalArc, formulaLength, center, f1, formulaF1, idObject, mode),
d (new VEllipticalArcData(radius1, radius2, formulaRadius1, formulaRadius2, rotationAngle))
{
CreateName();
FindF2(length);
}
//---------------------------------------------------------------------------------------------------------------------
VEllipticalArc::VEllipticalArc(qreal length, VPointF center, qreal radius1, qreal radius2, qreal f1,
qreal rotationAngle)
: VAbstractCurve(GOType::EllipticalArc, NULL_ID, Draw::Calculation),
d (new VEllipticalArcData(center, radius1, radius2, f1, rotationAngle))
VEllipticalArc::VEllipticalArc(qreal length, const VPointF &center, qreal radius1, qreal radius2, qreal f1,
qreal rotationAngle)
: VAbstractArc(GOType::EllipticalArc, center, f1, NULL_ID, Draw::Calculation),
d (new VEllipticalArcData(radius1, radius2, rotationAngle))
{
CreateName();
FindF2(length);
@ -97,7 +96,7 @@ VEllipticalArc::VEllipticalArc(qreal length, VPointF center, qreal radius1, qrea
* @param arc arc
*/
VEllipticalArc::VEllipticalArc(const VEllipticalArc &arc)
: VAbstractCurve(arc), d (arc.d)
: VAbstractArc(arc), d (arc.d)
{}
//---------------------------------------------------------------------------------------------------------------------
@ -112,11 +111,24 @@ VEllipticalArc &VEllipticalArc::operator =(const VEllipticalArc &arc)
{
return *this;
}
VAbstractCurve::operator=(arc);
VAbstractArc::operator=(arc);
d = arc.d;
return *this;
}
//---------------------------------------------------------------------------------------------------------------------
VEllipticalArc VEllipticalArc::Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix) const
{
const VPointF center = GetCenter().Rotate(originPoint, degrees);
const QPointF p1 = VPointF::RotatePF(originPoint, GetP1(), degrees);
const QPointF p2 = VPointF::RotatePF(originPoint, GetP2(), degrees);
const qreal f1 = QLineF(center, p1).angle() - GetRotationAngle();
const qreal f2 = QLineF(center, p2).angle() - GetRotationAngle();
VEllipticalArc elArc(center, GetRadius1(), GetRadius2(), f1, f2, GetRotationAngle());
elArc.setName(name() + prefix);
return elArc;
}
//---------------------------------------------------------------------------------------------------------------------
VEllipticalArc::~VEllipticalArc()
{}
@ -130,7 +142,7 @@ qreal VEllipticalArc::GetLength() const
{
qreal length = PathLength(GetPoints());
if (d->isFlipped)
if (IsFlipped())
{
length = length * -1;
}
@ -145,7 +157,7 @@ qreal VEllipticalArc::GetLength() const
*/
QPointF VEllipticalArc::GetP1() const
{
return GetPoint(d->f1);
return GetPoint(GetStartAngle());
}
//---------------------------------------------------------------------------------------------------------------------
@ -155,7 +167,7 @@ QPointF VEllipticalArc::GetP1() const
*/
QPointF VEllipticalArc::GetP2 () const
{
return GetPoint(d->f2);
return GetPoint(GetEndAngle());
}
//---------------------------------------------------------------------------------------------------------------------
@ -165,74 +177,121 @@ QPointF VEllipticalArc::GetP2 () const
*/
QPointF VEllipticalArc::GetPoint (qreal angle) const
{
// Original idea http://alex-black.ru/article.php?content=109#head_3
if (angle > 360 || angle < 0)
{// Filter incorect value of angle
QLineF dummy(0,0, 100, 0);
QLineF dummy(0, 0, 100, 0);
dummy.setAngle(angle);
angle = dummy.angle();
}
// p - point without rotation
qreal x = qAbs((d->radius1 * d->radius2)/
(qSqrt(d->radius2*d->radius2+d->radius1*d->radius1*qTan(M_PI*angle/180)*qTan(M_PI*angle/180))));
qreal y = qAbs(qTan(M_PI*angle/180) * x);
qreal x = 0;
qreal y = 0;
if (angle > 90 && angle <= 180)
{
x = -x;
qreal angleRad = qDegreesToRadians(angle);
const int n = GetQuadransRad(angleRad);
if (VFuzzyComparePossibleNulls(angleRad, 0) || VFuzzyComparePossibleNulls(angleRad, M_2PI) ||
VFuzzyComparePossibleNulls(angleRad, -M_2PI))
{ // 0 (360, -360) degress
x = d->radius1;
y = 0;
}
else if (angle > 180 && angle < 270)
{
x = -x;
y = -y;
}
else if (angle > 270)
{
y = -y;
}
else if (VFuzzyComparePossibleNulls(angle, 90))
{
else if (VFuzzyComparePossibleNulls(angleRad, M_PI_2) || VFuzzyComparePossibleNulls(angleRad, -3 * M_PI_2))
{ // 90 (-270) degress
x = 0;
y = d->radius2;
}
else if (VFuzzyComparePossibleNulls(angle, 270))
{
else if (VFuzzyComparePossibleNulls(angleRad, M_PI) || VFuzzyComparePossibleNulls(angleRad, -M_PI))
{ // 180 (-180) degress
x = -d->radius1;
y = 0;
}
else if (VFuzzyComparePossibleNulls(angleRad, 3 * M_PI_2) || VFuzzyComparePossibleNulls(angleRad, -M_PI_2))
{ // 270 (-90) degress
x = 0;
y = -d->radius2;
}
QPointF p ( GetCenter().x () + x, GetCenter().y () + y);
else
{ // cases between
const qreal r1Pow = qPow(d->radius1, 2);
const qreal r2Pow = qPow(d->radius2, 2);
const qreal angleTan = qTan(angleRad);
const qreal angleTan2 = qPow(angleTan, 2);
x = qSqrt((r1Pow * r2Pow) / (r1Pow * angleTan2 + r2Pow));
y = angleTan * x;
}
switch (n)
{
case 1:
x = +x;
y = +y;
break;
case 2:
x = -x;
y = +y;
break;
case 3:
x = -x;
y = -y;
break;
case 4:
x = +x;
y = -y;
break;
default:
break;
}
QPointF p (GetCenter().x() + x, GetCenter().y() + y);
// rotation of point
QLineF line(GetCenter().toQPointF(), p);
QLineF line(GetCenter(), p);
line.setAngle(line.angle() + GetRotationAngle());
return line.p2();
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief AngleArc calculate arc angle.
* @return angle in degree.
*/
qreal VEllipticalArc::AngleArc() const
int VEllipticalArc::GetQuadransRad(qreal &rad)
{
if ((qFuzzyIsNull(d->f1) && qFuzzyCompare(d->f2, 360)) ||
(qFuzzyCompare(d->f1, 360) && qFuzzyIsNull(d->f2)))
if (rad > M_PI)
{
return 360;
}
QLineF l1(0, 0, 100, 100);
l1.setAngle(d->f1);
QLineF l2(0, 0, 100, 100);
l2.setAngle(d->f2);
qreal ang = l1.angleTo(l2);
if (d->isFlipped)
{
ang = 360 - ang;
rad = rad - M_2PI;
}
return ang;
if (rad < -M_PI)
{
rad = rad + M_2PI;
}
int n = 0;
if (rad > 0)
{
if (rad >= 0 && rad <= M_PI_2)
{
n = 1;
rad = -rad;
}
else if (rad > M_PI_2 && rad <= M_PI)
{
n = 2;
rad = M_PI+rad;
}
}
else
{
if (rad <= 0 && rad >= -M_PI_2)
{
n = 4;
}
else if (rad < -M_PI_2 && rad >= -M_PI)
{
n = 3;
rad = M_PI-rad;
}
}
return n;
}
//---------------------------------------------------------------------------------------------------------------------
@ -247,7 +306,7 @@ QVector<qreal> VEllipticalArc::GetAngles() const
if (qFuzzyIsNull(angle))
{// Return the array that includes one angle
sectionAngle.append(d->f1);
sectionAngle.append(GetStartAngle());
return sectionAngle;
}
@ -284,7 +343,7 @@ QVector<QPointF> VEllipticalArc::GetPoints() const
QVector<qreal> sectionAngle = GetAngles();
qreal currentAngle;
d->isFlipped ? currentAngle = GetEndAngle() : currentAngle = GetStartAngle();
IsFlipped() ? currentAngle = GetEndAngle() : currentAngle = GetStartAngle();
for (int i = 0; i < sectionAngle.size(); ++i)
{
QPointF startPoint = GetPoint(currentAngle);
@ -348,13 +407,13 @@ QPointF VEllipticalArc::CutArc(const qreal &length, VEllipticalArc &arc1, VEllip
}
// the first arc has given length and startAngle just like in the origin arc
arc1 = VEllipticalArc (len, QString().setNum(length), d->center, d->radius1, d->radius2,
d->formulaRadius1, d->formulaRadius2, d->f1, d->formulaF1, d->rotationAngle,
arc1 = VEllipticalArc (len, QString().setNum(length), GetCenter(), d->radius1, d->radius2,
d->formulaRadius1, d->formulaRadius2, GetStartAngle(), GetFormulaF1(), d->rotationAngle,
getIdObject(), getMode());
// the second arc has startAngle just like endAngle of the first arc
// and it has endAngle just like endAngle of the origin arc
arc2 = VEllipticalArc (d->center, d->radius1, d->radius2, d->formulaRadius1, d->formulaRadius2,
arc1.GetEndAngle(), arc1.GetFormulaF2(), d->f2, d->formulaF2, d->rotationAngle,
arc2 = VEllipticalArc (GetCenter(), d->radius1, d->radius2, d->formulaRadius1, d->formulaRadius2,
arc1.GetEndAngle(), arc1.GetFormulaF2(), GetEndAngle(), GetFormulaF2(), d->rotationAngle,
getIdObject(), getMode());
return arc1.GetP1();
}
@ -368,34 +427,6 @@ QPointF VEllipticalArc::CutArc(const qreal &length) const
return this->CutArc(length, arc1, arc2);
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief setId keep id arc in data.
* @param id id arc in data.
*/
void VEllipticalArc::setId(const quint32 &id)
{
VAbstractCurve::setId(id);
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
QString VEllipticalArc::NameForHistory(const QString &toolName) const
{
QString name = toolName + QString(" %1").arg(this->GetCenter().name());
if (VAbstractCurve::id() != NULL_ID)
{
name += QString("_%1").arg(VAbstractCurve::id());
}
if (GetDuplicate() > 0)
{
name += QString("_%1").arg(GetDuplicate());
}
return name;
}
//---------------------------------------------------------------------------------------------------------------------
void VEllipticalArc::CreateName()
{
@ -420,7 +451,7 @@ void VEllipticalArc::FindF2(qreal length)
qreal gap = 180;
if (length < 0)
{
d->isFlipped = true;
SetFlipped(true);
gap = -gap;
}
while (length > MaxLength())
@ -432,15 +463,21 @@ void VEllipticalArc::FindF2(qreal length)
// first approximation of angle between start and end angles
qreal endAngle = GetStartAngle() + gap;
d->f2 = endAngle; // we need to set the end anngle, because we want to use GetLength()
// we need to set the end angle, because we want to use GetLength()
SetFormulaF2(QString::number(endAngle), endAngle);
qreal lenBez = GetLength(); // first approximation of length
qreal eps = 0.001 * qAbs(length);
const qreal eps = ToPixel(0.1, Unit::Mm);
while (qAbs(lenBez - length) > eps)
{
gap = gap/2;
if (gap < 0.0001)
{
break;
}
if (lenBez > length)
{ // we selected too big end angle
endAngle = endAngle - qAbs(gap);
@ -450,75 +487,21 @@ void VEllipticalArc::FindF2(qreal length)
endAngle = endAngle + qAbs(gap);
}
// we need to set d->f2, because we use it when we calculate GetLength
d->f2 = endAngle;
SetFormulaF2(QString::number(endAngle), endAngle);
lenBez = GetLength();
}
d->formulaF2 = QString().number(d->f2);
d->formulaLength = QString().number(qApp->fromPixel(lenBez));
SetFormulaF2(QString::number(endAngle), endAngle);
SetFormulaLength(QString::number(qApp->fromPixel(lenBez)));
}
//---------------------------------------------------------------------------------------------------------------------
qreal VEllipticalArc::MaxLength() const
{
const qreal h = ((d->radius1-d->radius2)*(d->radius1-d->radius2))/((d->radius1+d->radius2)*(d->radius1+d->radius2));
const qreal ellipseLength = M_PI*(d->radius1+d->radius2)*(1+3*h/(10+qSqrt(4-3*h)));
const qreal h = qPow(d->radius1 - d->radius2, 2) / qPow(d->radius1 + d->radius2, 2);
const qreal ellipseLength = M_PI * (d->radius1 + d->radius2) * (1+3*h/(10+qSqrt(4-3*h)));
return ellipseLength;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetF1 return start angle.
* @return angle in degree.
*/
QString VEllipticalArc::GetFormulaF1() const
{
return d->formulaF1;
}
//---------------------------------------------------------------------------------------------------------------------
void VEllipticalArc::SetFormulaF1(const QString &formula, qreal value)
{
d->formulaF1 = formula;
d->f1 = value;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetF1 return formula for start angle.
* @return string with formula.
*/
qreal VEllipticalArc::GetStartAngle() const
{
return d->f1;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetF2 return end angle.
* @return angle in degree.
*/
QString VEllipticalArc::GetFormulaF2() const
{
return d->formulaF2;
}
//---------------------------------------------------------------------------------------------------------------------
void VEllipticalArc::SetFormulaF2(const QString &formula, qreal value)
{
d->formulaF2 = formula;
d->f2 = value;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetF2 return formula for end angle.
* @return string with formula.
*/
qreal VEllipticalArc::GetEndAngle() const
{
return d->f2;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetRadius return arc major radius.
@ -582,32 +565,3 @@ qreal VEllipticalArc::GetRadius2() const
{
return d->radius2;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief GetCenter return center point.
* @return center point.
*/
VPointF VEllipticalArc::GetCenter() const
{
return d->center;
}
//---------------------------------------------------------------------------------------------------------------------
void VEllipticalArc::SetCenter(const VPointF &value)
{
d->center = value;
}
//---------------------------------------------------------------------------------------------------------------------
QString VEllipticalArc::GetFormulaLength() const
{
return d->formulaLength;
}
//---------------------------------------------------------------------------------------------------------------------
void VEllipticalArc::SetFormulaLength(const QString &formula, qreal value)
{
d->formulaLength = formula;
FindF2(value);
}

View file

@ -29,78 +29,63 @@
#ifndef VELLIPTICALARC_H
#define VELLIPTICALARC_H
#include "vabstractcurve.h"
#include "vabstractarc.h"
#include "vpointf.h"
#include <QCoreApplication>
class VEllipticalArcData;
class VEllipticalArc : public VAbstractCurve
class VEllipticalArc : public VAbstractArc
{
Q_DECLARE_TR_FUNCTIONS(VEllipticalArc)
public:
VEllipticalArc();
VEllipticalArc (VPointF center, qreal radius1, qreal radius2, QString formulaRadius1, QString formulaRadius2,
qreal f1, QString formulaF1, qreal f2, QString formulaF2, qreal rotationAngle,
quint32 idObject = 0, Draw mode = Draw::Calculation);
VEllipticalArc (VPointF center, qreal radius1, qreal radius2, qreal f1, qreal f2, qreal rotationAngle);
VEllipticalArc (qreal length, QString formulaLength, VPointF center, qreal radius1, qreal radius2,
QString formulaRadius1, QString formulaRadius2, qreal f1, QString formulaF1,
qreal rotationAngle, quint32 idObject = 0, Draw mode = Draw::Calculation);
VEllipticalArc (qreal length, VPointF center, qreal radius1, qreal radius2, qreal f1, qreal rotationAngle);
VEllipticalArc (const VPointF &center, qreal radius1, qreal radius2, const QString &formulaRadius1,
const QString &formulaRadius2, qreal f1, const QString &formulaF1, qreal f2,
const QString &formulaF2, qreal rotationAngle, quint32 idObject = 0, Draw mode = Draw::Calculation);
VEllipticalArc (const VPointF &center, qreal radius1, qreal radius2, qreal f1, qreal f2, qreal rotationAngle);
VEllipticalArc (qreal length, const QString &formulaLength, const VPointF &center, qreal radius1, qreal radius2,
const QString &formulaRadius1, const QString &formulaRadius2, qreal f1, const QString &formulaF1,
qreal rotationAngle, quint32 idObject = 0, Draw mode = Draw::Calculation);
VEllipticalArc (qreal length, const VPointF &center, qreal radius1, qreal radius2, qreal f1, qreal rotationAngle);
VEllipticalArc(const VEllipticalArc &arc);
VEllipticalArc& operator= (const VEllipticalArc &arc);
VEllipticalArc Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix = QString()) const;
virtual ~VEllipticalArc() Q_DECL_OVERRIDE;
QString GetFormulaF1 () const;
void SetFormulaF1 (const QString &formula, qreal value);
virtual qreal GetStartAngle () const Q_DECL_OVERRIDE;
qreal GetRotationAngle() const;
QString GetFormulaF2 () const;
void SetFormulaF2 (const QString &formula, qreal value);
virtual qreal GetEndAngle () const Q_DECL_OVERRIDE;
QString GetFormulaRadius1 () const;
void SetFormulaRadius1 (const QString &formula, qreal value);
qreal GetRadius1 () const;
qreal GetRotationAngle() const;
QString GetFormulaRadius2 () const;
void SetFormulaRadius2 (const QString &formula, qreal value);
qreal GetRadius2 () const;
QString GetFormulaRadius1 () const;
void SetFormulaRadius1 (const QString &formula, qreal value);
qreal GetRadius1 () const;
virtual qreal GetLength () const Q_DECL_OVERRIDE;
QString GetFormulaRadius2 () const;
void SetFormulaRadius2 (const QString &formula, qreal value);
qreal GetRadius2 () const;
QPointF GetP1() const;
QPointF GetP2() const;
VPointF GetCenter () const;
void SetCenter (const VPointF &value);
QString GetFormulaLength () const;
void SetFormulaLength (const QString &formula, qreal value);
virtual qreal GetLength () const Q_DECL_OVERRIDE;
QPointF GetP1() const;
QPointF GetP2 () const;
qreal AngleArc() const;
QVector<qreal> GetAngles () const;
virtual QVector<QPointF> GetPoints () const Q_DECL_OVERRIDE;
QPointF CutArc (const qreal &length, VEllipticalArc &arc1, VEllipticalArc &arc2) const;
QPointF CutArc (const qreal &length) const;
virtual void setId(const quint32 &id) Q_DECL_OVERRIDE;
virtual QString NameForHistory(const QString &toolName) const Q_DECL_OVERRIDE;
QPointF CutArc (const qreal &length, VEllipticalArc &arc1, VEllipticalArc &arc2) const;
QPointF CutArc (const qreal &length) const;
protected:
virtual void CreateName() Q_DECL_OVERRIDE;
virtual void FindF2(qreal length) Q_DECL_OVERRIDE;
private:
QSharedDataPointer<VEllipticalArcData> d;
void FindF2(qreal length);
qreal MaxLength() const;
QPointF GetPoint (qreal angle) const;
QVector<qreal> GetAngles () const;
qreal MaxLength() const;
QPointF GetPoint (qreal angle) const;
static int GetQuadransRad(qreal &rad);
};
Q_DECLARE_TYPEINFO(VEllipticalArc, Q_MOVABLE_TYPE);

View file

@ -13,81 +13,68 @@
class VEllipticalArcData : public QSharedData
{
public:
VEllipticalArcData ()
: f1(0), f2(0), formulaF1(QString()), formulaF2(QString()),
radius1(0), radius2(0), formulaRadius1(QString()), formulaRadius2(QString()),
center(VPointF()), isFlipped(false), formulaLength(), rotationAngle(0)
{}
VEllipticalArcData (VPointF center, qreal radius1, qreal radius2, QString formulaRadius1, QString formulaRadius2,
qreal f1, QString formulaF1, qreal f2, QString formulaF2, qreal rotationAngle)
: f1(f1), f2(f2), formulaF1(formulaF1), formulaF2(formulaF2),
radius1(radius1), radius2(radius2), formulaRadius1(formulaRadius1), formulaRadius2(formulaRadius2),
center(center), isFlipped(false), formulaLength(), rotationAngle(rotationAngle)
{}
VEllipticalArcData(VPointF center, qreal radius1, qreal radius2, qreal f1, qreal f2, qreal rotationAngle)
: f1(f1), f2(f2), formulaF1(QString().number(f1)),
formulaF2(QString().number(f2)), radius1(radius1), radius2(radius2),
formulaRadius1(QString().number(qApp->fromPixel(radius1))),
formulaRadius2(QString().number(qApp->fromPixel(radius2))),
center(center), isFlipped(false), formulaLength(), rotationAngle(rotationAngle)
{}
VEllipticalArcData (QString formulaLength, VPointF center, qreal radius1, qreal radius2,
QString formulaRadius1, QString formulaRadius2, qreal f1, QString formulaF1,
qreal rotationAngle)
: f1(f1), f2(0), formulaF1(formulaF1), formulaF2("0"), radius1(radius1),radius2(radius2),
formulaRadius1(formulaRadius1), formulaRadius2(formulaRadius2),
center(center), isFlipped(false), formulaLength(formulaLength), rotationAngle(rotationAngle)
{}
VEllipticalArcData(VPointF center, qreal radius1, qreal radius2, qreal f1, qreal rotationAngle)
: f1(f1), f2(0), formulaF1(QString().number(f1)), formulaF2("0"),
radius1(radius1), radius2(radius2),
formulaRadius1(QString().number(qApp->fromPixel(radius1))),
formulaRadius2(QString().number(qApp->fromPixel(radius2))),
center(center), isFlipped(false), formulaLength(), rotationAngle(rotationAngle)
{}
VEllipticalArcData(const VEllipticalArcData &arc)
: QSharedData(arc), f1(arc.f1), f2(arc.f2), formulaF1(arc.formulaF1), formulaF2(arc.formulaF2),
radius1(arc.radius1), radius2(arc.radius2),
formulaRadius1(arc.formulaRadius1), formulaRadius2(arc.formulaRadius2),
center(arc.center), isFlipped(arc.isFlipped), formulaLength(arc.formulaLength),
rotationAngle(arc.rotationAngle)
{}
VEllipticalArcData ();
VEllipticalArcData (qreal radius1, qreal radius2, const QString &formulaRadius1, const QString &formulaRadius2,
qreal rotationAngle);
VEllipticalArcData(qreal radius1, qreal radius2, qreal rotationAngle);
VEllipticalArcData(const VEllipticalArcData &arc);
virtual ~VEllipticalArcData();
/** @brief f1 start angle in degree. */
qreal f1;
/** @brief f2 end angle in degree. */
qreal f2;
/** @brief formulaF1 formula for start angle. */
QString formulaF1;
/** @brief formulaF2 formula for end angle. */
QString formulaF2;
/** @brief radius1 elliptical arc major radius. */
qreal radius1;
qreal radius1;
/** @brief radius2 elliptical arc minor radius. */
qreal radius2;
qreal radius2;
/** @brief formulaRadius1 formula for elliptical arc major radius. */
QString formulaRadius1;
QString formulaRadius1;
/** @brief formulaRadius2 formula for elliptical arc minor radius. */
QString formulaRadius2;
/** @brief center center point of arc. */
VPointF center;
bool isFlipped;
QString formulaLength;
QString formulaRadius2;
/** @brief rotationAngle in degree. */
qreal rotationAngle;
qreal rotationAngle;
private:
VEllipticalArcData &operator=(const VEllipticalArcData &) Q_DECL_EQ_DELETE;
};
//---------------------------------------------------------------------------------------------------------------------
VEllipticalArcData::VEllipticalArcData()
: radius1(0),
radius2(0),
formulaRadius1(),
formulaRadius2(),
rotationAngle(0)
{}
//---------------------------------------------------------------------------------------------------------------------
VEllipticalArcData::VEllipticalArcData(qreal radius1, qreal radius2, const QString &formulaRadius1,
const QString &formulaRadius2, qreal rotationAngle)
: radius1(radius1),
radius2(radius2),
formulaRadius1(formulaRadius1),
formulaRadius2(formulaRadius2),
rotationAngle(rotationAngle)
{}
//---------------------------------------------------------------------------------------------------------------------
VEllipticalArcData::VEllipticalArcData(qreal radius1, qreal radius2, qreal rotationAngle)
: radius1(radius1),
radius2(radius2),
formulaRadius1(QString().number(qApp->fromPixel(radius1))),
formulaRadius2(QString().number(qApp->fromPixel(radius2))),
rotationAngle(rotationAngle)
{}
//---------------------------------------------------------------------------------------------------------------------
VEllipticalArcData::VEllipticalArcData(const VEllipticalArcData &arc)
: QSharedData(arc),
radius1(arc.radius1),
radius2(arc.radius2),
formulaRadius1(arc.formulaRadius1),
formulaRadius2(arc.formulaRadius2),
rotationAngle(arc.rotationAngle)
{}
//---------------------------------------------------------------------------------------------------------------------
VEllipticalArcData::~VEllipticalArcData()
{}

View file

@ -13,7 +13,8 @@ SOURCES += \
$$PWD/vcubicbezier.cpp \
$$PWD/vabstractcubicbezier.cpp \
$$PWD/vabstractcubicbezierpath.cpp \
$$PWD/vcubicbezierpath.cpp
$$PWD/vcubicbezierpath.cpp \
$$PWD/vabstractarc.cpp
win32-msvc*:SOURCES += $$PWD/stable.cpp
@ -41,4 +42,6 @@ HEADERS += \
$$PWD/vabstractcubicbezier.h \
$$PWD/vabstractcubicbezierpath.h \
$$PWD/vcubicbezierpath.h \
$$PWD/vcubicbezierpath_p.h
$$PWD/vcubicbezierpath_p.h \
$$PWD/vabstractarc.h \
$$PWD/vabstractarc_p.h

View file

@ -29,8 +29,6 @@
#ifndef VGEOMETRYDEF_H
#define VGEOMETRYDEF_H
#include <QString>
enum class Draw : char { Calculation, Modeling, Layout };
enum class GOType : char { Point, Arc, EllipticalArc, Spline, SplinePath, CubicBezier, CubicBezierPath, Unknown };
enum class SplinePointPosition : char { FirstPoint, LastPoint };

View file

@ -506,7 +506,7 @@ double VGObject::GetEpsilon(const QPointF &p1, const QPointF &p2)
{
const double dx1 = p2.x() - p1.x();
const double dy1 = p2.y() - p1.y();
const double epsilon = 0.03 * (dx1 * dx1 + dy1 * dy1); //-V636
const double epsilon = 0.06 * (dx1 * dx1 + dy1 * dy1); //-V636
return epsilon;
}

View file

@ -85,13 +85,13 @@ public:
static QPointF addVector (const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k);
static void LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c);
static bool IsPointOnLineSegment (const QPointF &t, const QPointF &p1, const QPointF &p2);
static bool IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2);
static QVector<QPointF> GetReversePoints(const QVector<QPointF> &points);
static int GetLengthContour(const QVector<QPointF> &contour, const QVector<QPointF> &newPoints);
private:
QSharedDataPointer<VGObjectData> d;
static bool IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2);
static double PerpDotProduct(const QPointF &p1, const QPointF &p2, const QPointF &t);
static double GetEpsilon(const QPointF &p1, const QPointF &p2);

View file

@ -28,6 +28,7 @@
#include "vpointf.h"
#include "vpointf_p.h"
#include <QLineF>
#include <QPointF>
#include <QString>
@ -100,13 +101,16 @@ VPointF &VPointF::operator =(const VPointF &point)
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief toQPointF convert to QPointF
* @return QPointF point
*/
QPointF VPointF::toQPointF() const
VPointF::operator QPointF() const
{
return QPointF(d->_x, d->_y);
return toQPointF();
}
//---------------------------------------------------------------------------------------------------------------------
VPointF VPointF::Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix) const
{
const QPointF p = RotatePF(originPoint, toQPointF(), degrees);
return VPointF(p, name() + prefix, mx(), my());
}
//---------------------------------------------------------------------------------------------------------------------
@ -149,6 +153,12 @@ void VPointF::setMy(qreal my)
d->_my = my;
}
//---------------------------------------------------------------------------------------------------------------------
QPointF VPointF::toQPointF() const
{
return QPointF(d->_x, d->_y);
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief x return x coordinate
@ -188,3 +198,11 @@ void VPointF::setY(const qreal &value)
{
d->_y = value;
}
//---------------------------------------------------------------------------------------------------------------------
QPointF VPointF::RotatePF(const QPointF &originPoint, const QPointF &point, qreal degrees)
{
QLineF axis(originPoint, point);
axis.setAngle(axis.angle() + degrees);
return axis.p2();
}

View file

@ -58,6 +58,8 @@ public:
const Draw &mode = Draw::Calculation);
virtual ~VPointF() Q_DECL_OVERRIDE;
VPointF &operator=(const VPointF &point);
operator QPointF() const;
VPointF Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix = QString()) const;
qreal mx() const;
qreal my() const;
void setMx(qreal mx);
@ -67,6 +69,8 @@ public:
void setX(const qreal &value);
qreal y() const;
void setY(const qreal &value);
static QPointF RotatePF(const QPointF &originPoint, const QPointF &point, qreal degrees);
private:
QSharedDataPointer<VPointFData> d;
};

View file

@ -101,12 +101,26 @@ VSpline::VSpline(VPointF p1, VPointF p4, qreal angle1, const QString &angle1Form
const QString &angle2Formula, qreal c1Length, const QString &c1LengthFormula, qreal c2Length,
const QString &c2LengthFormula, quint32 idObject, Draw mode)
: VAbstractCubicBezier(GOType::Spline, idObject, mode),
d(new VSplineData(p1, p4, angle1, angle1Formula, angle2,angle2Formula, c1Length, c1LengthFormula, c2Length,
d(new VSplineData(p1, p4, angle1, angle1Formula, angle2, angle2Formula, c1Length, c1LengthFormula, c2Length,
c2LengthFormula))
{
CreateName();
}
//---------------------------------------------------------------------------------------------------------------------
VSpline VSpline::Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix) const
{
const VPointF p1 = GetP1().Rotate(originPoint, degrees);
const VPointF p4 = GetP4().Rotate(originPoint, degrees);
const QPointF p2 = VPointF::RotatePF(originPoint, GetP2(), degrees);
const QPointF p3 = VPointF::RotatePF(originPoint, GetP3(), degrees);
VSpline spl(p1, p2, p3, p4);
spl.setName(name() + prefix);
return spl;
}
//---------------------------------------------------------------------------------------------------------------------
VSpline::~VSpline()
{}
@ -118,7 +132,7 @@ VSpline::~VSpline()
*/
qreal VSpline::GetLength () const
{
return LengthBezier ( GetP1().toQPointF(), GetP2(), GetP3(), GetP4().toQPointF());
return LengthBezier ( GetP1(), GetP2(), GetP3(), GetP4());
}
//---------------------------------------------------------------------------------------------------------------------
@ -142,7 +156,7 @@ QPointF VSpline::CutSpline(qreal length, VSpline &spl1, VSpline &spl2) const
*/
QVector<QPointF> VSpline::GetPoints () const
{
return GetCubicBezierPoints(GetP1().toQPointF(), GetP2(), GetP3(), GetP4().toQPointF());
return GetCubicBezierPoints(GetP1(), GetP2(), GetP3(), GetP4());
}
//---------------------------------------------------------------------------------------------------------------------
@ -334,7 +348,7 @@ void VSpline::SetC2Length(qreal length, const QString &formula)
*/
qreal VSpline::GetKasm1() const
{
return QLineF(d->p1.toQPointF(), GetP2()).length() / VSplineData::GetL(d->p1.toQPointF(), d->p4.toQPointF(),
return QLineF(d->p1, GetP2()).length() / VSplineData::GetL(d->p1, d->p4,
d->kCurve);
}
@ -345,7 +359,7 @@ qreal VSpline::GetKasm1() const
*/
qreal VSpline::GetKasm2() const
{
return QLineF(d->p4.toQPointF(), GetP3()).length() / VSplineData::GetL(d->p1.toQPointF(), d->p4.toQPointF(),
return QLineF(d->p4, GetP3()).length() / VSplineData::GetL(d->p1, d->p4,
d->kCurve);
}
@ -455,8 +469,8 @@ qreal VSpline::ParamT (const QPointF &pBt) const
{
QVector<qreal> ts;
// Calculate t coefficient for each axis
ts += CalcT (GetP1().toQPointF().x(), GetP2().x(), GetP3().x(), GetP4().toQPointF().x(), pBt.x());
ts += CalcT (GetP1().toQPointF().y(), GetP2().y(), GetP3().y(), GetP4().toQPointF().y(), pBt.y());
ts += CalcT (GetP1().x(), GetP2().x(), GetP3().x(), GetP4().x(), pBt.x());
ts += CalcT (GetP1().y(), GetP2().y(), GetP3().y(), GetP4().y(), pBt.y());
if (ts.isEmpty())
{
@ -471,10 +485,10 @@ qreal VSpline::ParamT (const QPointF &pBt) const
for (int i=0; i< ts.size(); ++i)
{
const qreal t = ts.at(i);
const QPointF p0 = GetP1().toQPointF();
const QPointF p0 = GetP1();
const QPointF p1 = GetP2();
const QPointF p2 = GetP3();
const QPointF p3 = GetP4().toQPointF();
const QPointF p3 = GetP4();
//The explicit form of the Cubic Bézier curve
const qreal pointX = pow(1-t, 3)*p0.x() + 3*pow(1-t, 2)*t*p1.x() + 3*(1-t)*pow(t, 2)*p2.x() + pow(t, 3)*p3.x();
const qreal pointY = pow(1-t, 3)*p0.y() + 3*pow(1-t, 2)*t*p1.y() + 3*(1-t)*pow(t, 2)*p2.y() + pow(t, 3)*p3.y();

View file

@ -52,6 +52,7 @@ public:
VSpline (VPointF p1, VPointF p4, qreal angle1, const QString &angle1Formula, qreal angle2,
const QString &angle2Formula, qreal c1Length, const QString &c1LengthFormula, qreal c2Length,
const QString &c2LengthFormula, quint32 idObject = 0, Draw mode = Draw::Calculation);
VSpline Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix = QString()) const;
virtual ~VSpline();
VSpline &operator=(const VSpline &spl);

View file

@ -136,7 +136,7 @@ VSplineData::VSplineData(VPointF p1, VPointF p4, qreal angle1, qreal angle2, qre
c2LengthF("0"),
kCurve(kCurve)
{
const qreal L = GetL(p1.toQPointF(), p4.toQPointF(), kCurve);
const qreal L = GetL(p1, p4, kCurve);
QLineF p1p2(p1.x(), p1.y(), p1.x() + L * kAsm1, p1.y());
p1p2.setAngle(angle1);
@ -163,7 +163,7 @@ VSplineData::VSplineData(VPointF p1, QPointF p2, QPointF p3, VPointF p4)
c2LengthF("0"),
kCurve(1)
{
QLineF p1p2(p1.toQPointF(), p2);
QLineF p1p2(p1, p2);
angle1 = p1p2.angle();
angle1F = QString().number(angle1);
@ -171,7 +171,7 @@ VSplineData::VSplineData(VPointF p1, QPointF p2, QPointF p3, VPointF p4)
c1Length = p1p2.length();
c1LengthF = QString().number(qApp->fromPixel(c1Length));
QLineF p4p3(p4.toQPointF(), p3);
QLineF p4p3(p4, p3);
angle2 = p4p3.angle();
angle2F = QString().number(angle2);

View file

@ -57,12 +57,7 @@ VSplinePath::VSplinePath(const QVector<VFSplinePoint> &points, qreal kCurve, qui
return;
}
QVector<VSplinePoint> newPoints;
for (int i=0; i < points.size(); ++i)
{
newPoints.append(VSplinePoint());
}
QVector<VSplinePoint> newPoints(points.size());
for (qint32 i = 1; i <= points.size()-1; ++i)
{
const VFSplinePoint &p1 = points.at(i-1);
@ -106,6 +101,30 @@ VSplinePath::VSplinePath(const VSplinePath &splPath)
d(splPath.d)
{}
//---------------------------------------------------------------------------------------------------------------------
VSplinePath VSplinePath::Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix) const
{
QVector<VSplinePoint> newPoints(CountPoints());
for (qint32 i = 1; i <= CountSubSpl(); ++i)
{
const VSplinePoint &p1 = d->path.at(i-1);
const VSplinePoint &p2 = d->path.at(i);
VSpline spl = GetSpline(i).Rotate(originPoint, degrees);
newPoints[i-1].SetP(p1.P());
newPoints[i-1].SetAngle2(p1.Angle2(), spl.GetStartAngleFormula());
newPoints[i-1].SetLength2(spl.GetC1Length(), spl.GetC1LengthFormula());
newPoints[i].SetP(p2.P());
newPoints[i].SetAngle1(p2.Angle1(), spl.GetEndAngleFormula());
newPoints[i].SetLength1(spl.GetC2Length(), spl.GetC2LengthFormula());
}
VSplinePath splPath(newPoints);
splPath.setName(name() + prefix);
return splPath;
}
//---------------------------------------------------------------------------------------------------------------------
VSplinePath::~VSplinePath()
{}
@ -117,7 +136,7 @@ VSplinePath::~VSplinePath()
*/
void VSplinePath::append(const VSplinePoint &point)
{
if (d->path.size() > 0 && d->path.last().P().toQPointF() == point.P().toQPointF()) //-V807
if (d->path.size() > 0 && d->path.last().P() == point.P()) //-V807
{
return;
}

View file

@ -50,6 +50,7 @@ public:
Draw mode = Draw::Calculation);
VSplinePath(const QVector<VSplinePoint> &points, quint32 idObject = 0, Draw mode = Draw::Calculation);
VSplinePath(const VSplinePath& splPath);
VSplinePath Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix = QString()) const;
virtual ~VSplinePath() Q_DECL_OVERRIDE;
VSplinePath &operator=(const VSplinePath &path);

View file

@ -29,6 +29,8 @@
#include "vabstractdetail.h"
#include "vabstractdetail_p.h"
#include "../vgeometry/vgobject.h"
#include <QVector>
#include <QPointF>
#include <QLineF>
@ -327,37 +329,83 @@ QVector<QPointF> VAbstractDetail::CheckLoops(const QVector<QPointF> &points)
continue;
}
enum LoopIntersectType { NoIntersection, BoundedIntersection, ParallelIntersection };
QPointF crosPoint;
QLineF::IntersectType intersect = QLineF::NoIntersection;
LoopIntersectType status = NoIntersection;
const QLineF line1(points.at(i), points.at(i+1));
// Because a path can contains several loops we will seek the last and only then remove the loop(s)
// That's why we parse from the end
for (j = count-2; j >= i+2; --j)
{
const QLineF line2(points.at(j), points.at(j+1));
intersect = line1.intersect(line2, &crosPoint);
if (intersect == QLineF::BoundedIntersection && not (i == 0 && j+1 == count-1 && closed))
const QLineF::IntersectType intersect = line1.intersect(line2, &crosPoint);
if (intersect == QLineF::NoIntersection)
{ // According to the documentation QLineF::NoIntersection indicates that the lines do not intersect;
// i.e. they are parallel. But parallel also mean they can be on the same line.
// Method IsPointOnLineviaPDP will check it.
if (VGObject::IsPointOnLineviaPDP(points.at(j), points.at(i), points.at(i+1))
// Next cases are valid for us.
&& line1.p2() != line2.p2()
&& line1.p1() != line2.p1()
&& line1.p2() != line2.p1()
&& line1.p1() != line2.p2())
{
// Left to catch case where segments are on the same line, but do not have real intersections.
QLineF tmpLine1 = line1;
QLineF tmpLine2 = line2;
tmpLine1.setAngle(tmpLine1.angle()+90);
QPointF tmpCrosPoint;
const QLineF::IntersectType tmpIntrs1 = tmpLine1.intersect(tmpLine2, &tmpCrosPoint);
tmpLine1 = line1;
tmpLine2.setAngle(tmpLine2.angle()+90);
const QLineF::IntersectType tmpIntrs2 = tmpLine1.intersect(tmpLine2, &tmpCrosPoint);
if (tmpIntrs1 == QLineF::BoundedIntersection || tmpIntrs2 == QLineF::BoundedIntersection)
{ // Now we really sure that lines are on the same lines and have real intersections.
status = ParallelIntersection;
break;
}
}
}
else if (intersect == QLineF::BoundedIntersection && not (i == 0 && j+1 == count-1 && closed))
{ // Break, but not if intersects the first edge and the last edge in closed path
if (line1.p1() != crosPoint && line1.p2() != crosPoint &&
line2.p1() != crosPoint && line2.p2() != crosPoint)
{ // Break, but not if loop creates crosPoint when it is first or last point of lines
status = BoundedIntersection;
break;
}
}
intersect = QLineF::NoIntersection;
status = NoIntersection;
}
if (intersect == QLineF::BoundedIntersection)
switch (status)
{
/*We have found loop.*/
ekvPoints.append(points.at(i));
ekvPoints.append(crosPoint);
i = j;
}
else
{
/*We have not found loop.*/
ekvPoints.append(points.at(i));
case ParallelIntersection:
/*We have found a loop.*/
// Theoretically there is no big difference which point j or j+1 to select.
// In the end we will draw a line in any case.
ekvPoints.append(points.at(i));
ekvPoints.append(points.at(j+1));
i = j;
break;
case BoundedIntersection:
/*We have found a loop.*/
ekvPoints.append(points.at(i));
ekvPoints.append(crosPoint);
i = j;
break;
case NoIntersection:
/*We have not found loop.*/
ekvPoints.append(points.at(i));
break;
default:
break;
}
}
return ekvPoints;

View file

@ -102,6 +102,7 @@ enum class Tool : ToolVisHolderType
TrueDarts,
UnionDetails,
Group,
Rotation,
LAST_ONE_DO_NOT_USE //add new stuffs above this, this constant must be last and never used
};
@ -110,6 +111,7 @@ enum class Vis : ToolVisHolderType
ControlPointSpline = static_cast<ToolVisHolderType>(Tool::LAST_ONE_DO_NOT_USE),
GraphicsSimpleTextItem,
SimplePoint,
SimpleCurve,
Line,
Path,
ToolAlongLine,
@ -139,7 +141,8 @@ enum class Vis : ToolVisHolderType
ToolCutSplinePath,
ToolLineIntersectAxis,
ToolCurveIntersectAxis,
ToolTrueDarts
ToolTrueDarts,
ToolRotation
};
enum class VarType : char { Measurement, Increment, LineLength, CurveLength, LineAngle, CurveAngle, ArcRadius,
@ -629,4 +632,95 @@ static inline bool VFuzzyComparePossibleNulls(double p1, double p2)
}
}
/****************************************************************************
** This file is derived from code bearing the following notice:
** The sole author of this file, Adam Higerd, has explicitly disclaimed all
** copyright interest and protection for the content within. This file has
** been placed in the public domain according to United States copyright
** statute and case law. In jurisdictions where this public domain dedication
** is not legally recognized, anyone who receives a copy of this file is
** permitted to use, modify, duplicate, and redistribute this file, in whole
** or in part, with no restrictions or conditions. In these jurisdictions,
** this file shall be copyright (C) 2006-2008 by Adam Higerd.
****************************************************************************/
#define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface<PUB, PUB##Private> qxt_d;
#define QXT_DECLARE_PUBLIC(PUB) friend class PUB;
#define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this);
#define QXT_D(PUB) PUB##Private& d = qxt_d()
#define QXT_P(PUB) PUB& p = qxt_p()
template <typename PUB>
class QxtPrivate
{
public:
QxtPrivate(): qxt_p_ptr(nullptr)
{}
virtual ~QxtPrivate()
{}
inline void QXT_setPublic(PUB* pub)
{
qxt_p_ptr = pub;
}
protected:
inline PUB& qxt_p()
{
return *qxt_p_ptr;
}
inline const PUB& qxt_p() const
{
return *qxt_p_ptr;
}
inline PUB* qxt_ptr()
{
return qxt_p_ptr;
}
inline const PUB* qxt_ptr() const
{
return qxt_p_ptr;
}
private:
Q_DISABLE_COPY(QxtPrivate)
PUB* qxt_p_ptr;
};
template <typename PUB, typename PVT>
class QxtPrivateInterface
{
friend class QxtPrivate<PUB>;
public:
QxtPrivateInterface() : pvt(new PVT)
{}
~QxtPrivateInterface()
{
delete pvt;
}
inline void setPublic(PUB* pub)
{
pvt->QXT_setPublic(pub);
}
inline PVT& operator()()
{
return *static_cast<PVT*>(pvt);
}
inline const PVT& operator()() const
{
return *static_cast<PVT*>(pvt);
}
inline PVT * operator->()
{
return static_cast<PVT*>(pvt);
}
inline const PVT * operator->() const
{
return static_cast<PVT*>(pvt);
}
private:
Q_DISABLE_COPY(QxtPrivateInterface)
QxtPrivate<PUB>* pvt;
};
#endif // DEF_H

View file

@ -0,0 +1,729 @@
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
/*!
\class QxtCsvModel
\brief The QxtCsvModel class provides a QAbstractTableModel for CSV Files
*/
#include "qxtcsvmodel.h"
#include <QFile>
#include <QTextStream>
#include <QDebug>
class QxtCsvModelPrivate : public QxtPrivate<QxtCsvModel>
{
public:
QxtCsvModelPrivate() : csvData(), header(), maxColumn(0), quoteMode(QxtCsvModel::DefaultQuoteMode)
{}
QXT_DECLARE_PUBLIC(QxtCsvModel)
QList<QStringList> csvData;
QStringList header;
int maxColumn;
QxtCsvModel::QuoteMode quoteMode;
};
#ifdef Q_CC_GNU
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#endif
/*!
Creates an empty QxtCsvModel with parent \a parent.
*/
QxtCsvModel::QxtCsvModel(QObject *parent) : QAbstractTableModel(parent)
{
QXT_INIT_PRIVATE(QxtCsvModel);
}
/*!
Creates a QxtCsvModel with the parent \a parent and content loaded from \a file.
See \a setSource for information on the \a withHeader and \a separator properties, or
if you need control over the quoting method or codec used to parse the file.
\sa setSource
*/
QxtCsvModel::QxtCsvModel(QIODevice *file, QObject *parent, bool withHeader, QChar separator)
: QAbstractTableModel(parent)
{
QXT_INIT_PRIVATE(QxtCsvModel);
setSource(file, withHeader, separator);
}
/*!
\overload
Creates a QxtCsvModel with the parent \a parent and content loaded from \a file.
See \a setSource for information on the \a withHeader and \a separator properties, or
if you need control over the quoting method or codec used to parse the file.
\sa setSource
*/
QxtCsvModel::QxtCsvModel(const QString filename, QObject *parent, bool withHeader, QChar separator)
: QAbstractTableModel(parent)
{
QXT_INIT_PRIVATE(QxtCsvModel);
QFile src(filename);
setSource(&src, withHeader, separator);
}
#ifdef Q_CC_GNU
#pragma GCC diagnostic pop
#endif
QxtCsvModel::~QxtCsvModel()
{}
/*!
\reimp
*/
int QxtCsvModel::rowCount(const QModelIndex& parent) const
{
if (parent.row() != -1 && parent.column() != -1)
{
return 0;
}
return qxt_d().csvData.count();
}
/*!
\reimp
*/
int QxtCsvModel::columnCount(const QModelIndex& parent) const
{
if (parent.row() != -1 && parent.column() != -1)
{
return 0;
}
return qxt_d().maxColumn;
}
/*!
\reimp
*/
QVariant QxtCsvModel::data(const QModelIndex& index, int role) const
{
if (index.parent() != QModelIndex())
{
return QVariant();
}
if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole)
{
if (index.row() < 0 || index.column() < 0 || index.row() >= rowCount())
{
return QVariant();
}
const QStringList& row = qxt_d().csvData[index.row()];
if (index.column() >= row.length())
{
return QVariant();
}
return row[index.column()];
}
return QVariant();
}
/*!
\reimp
*/
QVariant QxtCsvModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (section < qxt_d().header.count() && orientation == Qt::Horizontal && (role == Qt::DisplayRole
|| role == Qt::EditRole
|| role == Qt::UserRole))
{
return qxt_d().header[section];
}
else
{
return QAbstractTableModel::headerData(section, orientation, role);
}
}
/*!
\overload
Reads in a CSV file from the provided \a file using \a codec.
*/
void QxtCsvModel::setSource(const QString filename, bool withHeader, QChar separator, QTextCodec* codec)
{
QFile src(filename);
setSource(&src, withHeader, separator, codec);
}
/*!
Reads in a CSV file from the provided \a file using \a codec.
The value of \a separator will be used to delimit fields, subject to the specified \a quoteMode.
If \a withHeader is set to true, the first line of the file will be used to populate the model's
horizontal header.
\sa quoteMode
*/
void QxtCsvModel::setSource(QIODevice *file, bool withHeader, QChar separator, QTextCodec* codec)
{
QxtCsvModelPrivate* d_ptr = &qxt_d();
bool headerSet = !withHeader;
if (not file->isOpen())
{
file->open(QIODevice::ReadOnly);
}
if (withHeader)
{
d_ptr->maxColumn = 0;
}
else
{
d_ptr->maxColumn = d_ptr->header.size();
}
d_ptr->csvData.clear();
QStringList row;
QString field;
QChar quote;
QChar ch, buffer(0);
bool readCR = false;
QTextStream stream(file);
if (codec)
{
stream.setCodec(codec);
}
else
{
stream.setAutoDetectUnicode(true);
}
while (not stream.atEnd())
{
if (buffer != QChar(0))
{
ch = buffer;
buffer = QChar(0);
}
else
{
stream >> ch;
}
if (ch == '\n' && readCR)
{
continue;
}
else if (ch == '\r')
{
readCR = true;
}
else
{
readCR = false;
}
if (ch != separator && (ch.category() == QChar::Separator_Line || ch.category() == QChar::Separator_Paragraph
|| ch.category() == QChar::Other_Control))
{
row << field;
field.clear();
if (not row.isEmpty())
{
if (not headerSet)
{
d_ptr->header = row;
headerSet = true;
}
else
{
d_ptr->csvData.append(row);
}
if (row.length() > d_ptr->maxColumn)
{
d_ptr->maxColumn = row.length();
}
}
row.clear();
}
else if ((d_ptr->quoteMode & DoubleQuote && ch == '"') || (d_ptr->quoteMode & SingleQuote && ch == '\''))
{
quote = ch;
do
{
stream >> ch;
if (ch == '\\' && d_ptr->quoteMode & BackslashEscape)
{
stream >> ch;
}
else if (ch == quote)
{
if (d_ptr->quoteMode & TwoQuoteEscape)
{
stream >> buffer;
if (buffer == quote)
{
buffer = QChar(0);
field.append(ch);
continue;
}
}
break;
}
field.append(ch);
} while (!stream.atEnd());
}
else if (ch == separator)
{
row << field;
field.clear();
}
else
{
field.append(ch);
}
}
if (not field.isEmpty())
{
row << field;
}
if (not row.isEmpty())
{
if (not headerSet)
{
d_ptr->header = row;
}
else
{
d_ptr->csvData.append(row);
}
}
file->close();
}
/*!
Sets the horizontal headers of the model to the values provided in \a data.
*/
void QxtCsvModel::setHeaderData(const QStringList& data)
{
qxt_d().header = data;
emit headerDataChanged(Qt::Horizontal, 0, data.count());
}
/*!
\reimp
*/
bool QxtCsvModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant& value, int role)
{
if (orientation != Qt::Horizontal)
{
return false; // We don't support the vertical header
}
if (role != Qt::DisplayRole && role != Qt::EditRole)
{
return false; // We don't support any other roles
}
if (section < 0)
{
return false; // Bogus input
}
while (section > qxt_d().header.size())
{
qxt_d().header << QString();
}
qxt_d().header[section] = value.toString();
emit headerDataChanged(Qt::Horizontal, section, section);
return true;
}
/*!
\reimp
*/
bool QxtCsvModel::setData(const QModelIndex& index, const QVariant& data, int role)
{
if (index.parent() != QModelIndex())
{
return false;
}
if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole)
{
if (index.row() >= rowCount() || index.column() >= columnCount() || index.row() < 0 || index.column() < 0)
{
return false;
}
QStringList& row = qxt_d().csvData[index.row()];
while (row.length() <= index.column())
{
row << QString();
}
row[index.column()] = data.toString();
emit dataChanged(index, index);
return true;
}
return false;
}
/*!
\reimp
*/
bool QxtCsvModel::insertRow(int row, const QModelIndex& parent)
{
return insertRows(row, 1, parent);
}
/*!
\reimp
*/
bool QxtCsvModel::insertRows(int row, int count, const QModelIndex& parent)
{
if (parent != QModelIndex() || row < 0)
{
return false;
}
emit beginInsertRows(parent, row, row + count);
QxtCsvModelPrivate& d_ptr = qxt_d();
if (row >= rowCount())
{
for(int i = 0; i < count; i++)
{
d_ptr.csvData << QStringList();
}
}
else
{
for(int i = 0; i < count; i++)
{
d_ptr.csvData.insert(row, QStringList());
}
}
emit endInsertRows();
return true;
}
/*!
\reimp
*/
bool QxtCsvModel::removeRow(int row, const QModelIndex& parent)
{
return removeRows(row, 1, parent);
}
/*!
\reimp
*/
bool QxtCsvModel::removeRows(int row, int count, const QModelIndex& parent)
{
if (parent != QModelIndex() || row < 0)
{
return false;
}
if (row >= rowCount())
{
return false;
}
if (row + count >= rowCount())
{
count = rowCount() - row;
}
emit beginRemoveRows(parent, row, row + count);
QxtCsvModelPrivate& d_ptr = qxt_d();
for (int i = 0;i < count;i++)
{
d_ptr.csvData.removeAt(row);
}
emit endRemoveRows();
return true;
}
/*!
\reimp
*/
bool QxtCsvModel::insertColumn(int col, const QModelIndex& parent)
{
return insertColumns(col, 1, parent);
}
/*!
\reimp
*/
bool QxtCsvModel::insertColumns(int col, int count, const QModelIndex& parent)
{
if (parent != QModelIndex() || col < 0)
{
return false;
}
beginInsertColumns(parent, col, col + count - 1);
QxtCsvModelPrivate& d_ptr = qxt_d();
for (int i = 0; i < rowCount(); i++)
{
QStringList& row = d_ptr.csvData[i];
while (col >= row.length())
{
row.append(QString());
}
for (int j = 0; j < count; j++)
{
row.insert(col, QString());
}
}
for (int i = 0; i < count ;i++)
{
d_ptr.header.insert(col, QString());
}
d_ptr.maxColumn += count;
endInsertColumns();
return true;
}
/*!
\reimp
*/
bool QxtCsvModel::removeColumn(int col, const QModelIndex& parent)
{
return removeColumns(col, 1, parent);
}
/*!
\reimp
*/
bool QxtCsvModel::removeColumns(int col, int count, const QModelIndex& parent)
{
if (parent != QModelIndex() || col < 0)
{
return false;
}
if (col >= columnCount())
{
return false;
}
if (col + count >= columnCount())
{
count = columnCount() - col;
}
emit beginRemoveColumns(parent, col, col + count);
QxtCsvModelPrivate& d_ptr = qxt_d();
QString before, after;
for (int i = 0; i < rowCount(); i++)
{
for (int j = 0; j < count; j++)
{
d_ptr.csvData[i].removeAt(col);
}
}
for (int i = 0; i < count; i++)
{
d_ptr.header.removeAt(col);
}
emit endRemoveColumns();
return true;
}
static QString qxt_addCsvQuotes(QxtCsvModel::QuoteMode mode, QString field)
{
bool addDoubleQuotes = ((mode & QxtCsvModel::DoubleQuote) && field.contains('"'));
bool addSingleQuotes = ((mode & QxtCsvModel::SingleQuote) && field.contains('\''));
bool quoteField = (mode & QxtCsvModel::AlwaysQuoteOutput) || addDoubleQuotes || addSingleQuotes;
if (quoteField && !addDoubleQuotes && !addSingleQuotes)
{
if (mode & QxtCsvModel::DoubleQuote)
{
addDoubleQuotes = true;
}
else if(mode & QxtCsvModel::SingleQuote)
{
addSingleQuotes = true;
}
}
if (mode & QxtCsvModel::BackslashEscape)
{
if (addDoubleQuotes)
{
return '"' + field.replace("\\", "\\\\").replace("\"", "\\\"") + '"';
}
if (addSingleQuotes)
{
return '\'' + field.replace("\\", "\\\\").replace("'", "\\'") + '\'';
}
}
else
{
if (addDoubleQuotes)
{
return '"' + field.replace("\"", "\"\"") + '"';
}
if (addSingleQuotes)
{
return '\'' + field.replace("'", "''") + '\'';
}
}
return field;
}
/*!
Outputs the content of the model as a CSV file to the device \a dest using \a codec.
Fields in the output file will be separated by \a separator. Set \a withHeader to true
to output a row of headers at the top of the file.
*/
void QxtCsvModel::toCSV(QIODevice* dest, bool withHeader, QChar separator, QTextCodec* codec) const
{
const QxtCsvModelPrivate& d_ptr = qxt_d();
int row, col, rows, cols;
rows = rowCount();
cols = columnCount();
QString data;
if (not dest->isOpen())
{
dest->open(QIODevice::WriteOnly | QIODevice::Truncate);
}
QTextStream stream(dest);
if (codec)
{
stream.setCodec(codec);
}
if (withHeader)
{
data = "";
for (col = 0; col < cols; ++col)
{
if (col > 0)
{
data += separator;
}
data += qxt_addCsvQuotes(d_ptr.quoteMode, d_ptr.header.at(col));
}
stream << data << endl;
}
for (row = 0; row < rows; ++row)
{
const QStringList& rowData = d_ptr.csvData[row];
data = "";
for (col = 0; col < cols; ++col)
{
if (col > 0)
{
data += separator;
}
if (col < rowData.length())
{
data += qxt_addCsvQuotes(d_ptr.quoteMode, rowData.at(col));
}
else
{
data += qxt_addCsvQuotes(d_ptr.quoteMode, QString());
}
}
stream << data << endl;
}
stream << flush;
dest->close();
}
/*!
\overload
Outputs the content of the model as a CSV file to the file specified by \a filename using \a codec.
Fields in the output file will be separated by \a separator. Set \a withHeader to true
to output a row of headers at the top of the file.
*/
void QxtCsvModel::toCSV(const QString filename, bool withHeader, QChar separator, QTextCodec* codec) const
{
QFile dest(filename);
toCSV(&dest, withHeader, separator, codec);
}
/*!
\reimp
*/
Qt::ItemFlags QxtCsvModel::flags(const QModelIndex& index) const
{
return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
}
/*!
* Returns the current quoting mode.
* \sa setQuoteMode
*/
QxtCsvModel::QuoteMode QxtCsvModel::quoteMode() const
{
return qxt_d().quoteMode;
}
/*!
* Sets the current quoting mode. The default quoting mode is BothQuotes | BackslashEscape.
*
* The quoting mode determines what kinds of quoting is used for reading and writing CSV files.
* \sa quoteMode
* \sa QuoteOption
*/
void QxtCsvModel::setQuoteMode(QuoteMode mode)
{
qxt_d().quoteMode = mode;
}
/*!
Sets the content of the cell at row \a row and column \a column to \a value.
\sa text
*/
void QxtCsvModel::setText(int row, int column, const QString& value)
{
setData(index(row, column), value);
}
/*!
Fetches the content of the cell at row \a row and column \a column.
\sa setText
*/
QString QxtCsvModel::text(int row, int column) const
{
return data(index(row, column)).toString();
}
/*!
Sets the content of the header for column \a column to \a value.
\sa headerText
*/
void QxtCsvModel::setHeaderText(int column, const QString& value)
{
setHeaderData(column, Qt::Horizontal, value);
}
/*!
Fetches the content of the cell at row \a row and column \a column.
\sa setText
*/
QString QxtCsvModel::headerText(int column) const
{
return headerData(column, Qt::Horizontal).toString();
}

View file

@ -0,0 +1,113 @@
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** * Neither the name of the LibQxt project nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org> <foundation@libqxt.org>
*****************************************************************************/
#ifndef QXTCSVMODEL_H
#define QXTCSVMODEL_H
#include <QAbstractTableModel>
#include <QVariant>
#include <QIODevice>
#include <QChar>
#include <QString>
#include <QStringList>
#include <QModelIndex>
#include <def.h>
class QTextCodec;
class QxtCsvModelPrivate;
class QxtCsvModel : public QAbstractTableModel
{
Q_OBJECT
public:
QxtCsvModel(QObject *parent = nullptr);
explicit QxtCsvModel(QIODevice *file, QObject *parent = nullptr, bool withHeader = false, QChar separator = ',');
explicit QxtCsvModel(const QString filename, QObject *parent = nullptr, bool withHeader = false,
QChar separator = ',');
virtual ~QxtCsvModel();
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
virtual bool setData(const QModelIndex& index, const QVariant& data, int role = Qt::EditRole) Q_DECL_OVERRIDE;
virtual QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
virtual bool setHeaderData(int section, Qt::Orientation orientation, const QVariant& value,
int role = Qt::DisplayRole) Q_DECL_OVERRIDE;
void setHeaderData(const QStringList& data);
QString text(int row, int column) const;
void setText(int row, int column, const QString& value);
QString headerText(int column) const;
void setHeaderText(int column, const QString& value);
bool insertRow(int row, const QModelIndex& parent = QModelIndex());
virtual bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()) Q_DECL_OVERRIDE;
bool removeRow(int row, const QModelIndex& parent = QModelIndex());
virtual bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) Q_DECL_OVERRIDE;
bool insertColumn(int col, const QModelIndex& parent = QModelIndex());
virtual bool insertColumns(int col, int count, const QModelIndex& parent = QModelIndex()) Q_DECL_OVERRIDE;
bool removeColumn(int col, const QModelIndex& parent = QModelIndex());
virtual bool removeColumns(int col, int count, const QModelIndex& parent = QModelIndex()) Q_DECL_OVERRIDE;
void setSource(QIODevice *file, bool withHeader = false, QChar separator = ',', QTextCodec* codec = nullptr);
void setSource(const QString filename, bool withHeader = false, QChar separator = ',', QTextCodec* codec = nullptr);
void toCSV(QIODevice *file, bool withHeader = false, QChar separator = ',', QTextCodec* codec = nullptr) const;
void toCSV(const QString filename, bool withHeader = false, QChar separator = ',',
QTextCodec* codec = nullptr) const;
enum QuoteOption { NoQuotes = 0,
SingleQuote = 1,
DoubleQuote = 2,
BothQuotes = 3,
NoEscape = 0,
TwoQuoteEscape = 4,
BackslashEscape = 8,
AlwaysQuoteOutput = 16,
DefaultQuoteMode = BothQuotes | BackslashEscape | AlwaysQuoteOutput };
Q_DECLARE_FLAGS(QuoteMode, QuoteOption)
QuoteMode quoteMode() const;
void setQuoteMode(QuoteMode mode);
virtual Qt::ItemFlags flags(const QModelIndex& index) const Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(QxtCsvModel)
QXT_DECLARE_PRIVATE(QxtCsvModel)
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QxtCsvModel::QuoteMode)
#endif // QXTCSVMODEL_H

View file

@ -9,7 +9,8 @@ SOURCES += \
$$PWD/projectversion.cpp \
$$PWD/vcommonsettings.cpp \
$$PWD/vtapesettings.cpp \
$$PWD/commandoptions.cpp
$$PWD/commandoptions.cpp \
$$PWD/qxtcsvmodel.cpp
win32-msvc*:SOURCES += $$PWD/stable.cpp
@ -27,7 +28,8 @@ HEADERS += \
$$PWD/debugbreak.h \
$$PWD/vlockguard.h \
$$PWD/vsysexits.h \
$$PWD/commandoptions.h
$$PWD/commandoptions.h \
$$PWD/qxtcsvmodel.h
# Qt's versions
# 5.0.0, 5.0.1, 5.0.2

View file

@ -30,12 +30,17 @@
#include <QApplication>
#include <QDir>
#include <QTextCodec>
const QString VTapeSettings::SettingDataBaseGeometry = QStringLiteral("database/geometry");
const QString VTapeSettings::SettingDefHeight = QStringLiteral("gradation/defHeight");
const QString VTapeSettings::SettingDefSize = QStringLiteral("gradation/defHeight");
const QString VTapeSettings::SettingCSVWithHeader = QStringLiteral("csv/withHeader");
const QString VTapeSettings::SettingCSVCodec = QStringLiteral("csv/withCodec");
const QString VTapeSettings::SettingCSVSeparator = QStringLiteral("csv/withSeparator");
//---------------------------------------------------------------------------------------------------------------------
VTapeSettings::VTapeSettings(Format format, Scope scope, const QString &organization, const QString &application,
QObject *parent)
@ -78,3 +83,88 @@ int VTapeSettings::GetDefSize() const
{
return value(SettingDefSize, 50).toInt();
}
//---------------------------------------------------------------------------------------------------------------------
void VTapeSettings::SetCSVWithHeader(bool withHeader)
{
setValue(SettingCSVWithHeader, withHeader);
}
//---------------------------------------------------------------------------------------------------------------------
bool VTapeSettings::GetCSVWithHeader() const
{
return value(SettingCSVWithHeader, GetDefCSVWithHeader()).toBool();
}
//---------------------------------------------------------------------------------------------------------------------
bool VTapeSettings::GetDefCSVWithHeader() const
{
return false;
}
//---------------------------------------------------------------------------------------------------------------------
void VTapeSettings::SetCSVCodec(int mib)
{
setValue(SettingCSVCodec, mib);
}
//---------------------------------------------------------------------------------------------------------------------
int VTapeSettings::GetCSVCodec() const
{
return value(SettingCSVCodec, GetDefCSVCodec()).toInt();
}
//---------------------------------------------------------------------------------------------------------------------
int VTapeSettings::GetDefCSVCodec() const
{
return QTextCodec::codecForLocale()->mibEnum();
}
//---------------------------------------------------------------------------------------------------------------------
void VTapeSettings::SetCSVSeparator(const QChar &separator)
{
switch(separator.toLatin1())
{
case '\t':
setValue(SettingCSVSeparator, 0);
break;
case ';':
setValue(SettingCSVSeparator, 1);
break;
case ' ':
setValue(SettingCSVSeparator, 2);
break;
case ',':
default:
setValue(SettingCSVSeparator, 3);
break;
}
}
//---------------------------------------------------------------------------------------------------------------------
QChar VTapeSettings::GetCSVSeparator() const
{
const quint8 separator = static_cast<quint8>(value(SettingCSVSeparator, 3).toUInt());
switch(separator)
{
case 0:
return QChar('\t');
break;
case 1:
return QChar(';');
break;
case 2:
return QChar(' ');
break;
case 3:
default:
return QChar(',');
break;
}
}
//---------------------------------------------------------------------------------------------------------------------
QChar VTapeSettings::GetDefCSVSeparator() const
{
return QChar(',');
}

View file

@ -47,12 +47,27 @@ public:
void SetDefSize(int value);
int GetDefSize() const;
void SetCSVWithHeader(bool withHeader);
bool GetCSVWithHeader() const;
bool GetDefCSVWithHeader() const;
void SetCSVCodec(int mib);
int GetCSVCodec() const;
int GetDefCSVCodec() const;
void SetCSVSeparator(const QChar &separator);
QChar GetCSVSeparator() const;
QChar GetDefCSVSeparator() const;
private:
Q_DISABLE_COPY(VTapeSettings)
static const QString SettingDataBaseGeometry;
static const QString SettingDefHeight;
static const QString SettingDefSize;
static const QString SettingCSVWithHeader;
static const QString SettingCSVCodec;
static const QString SettingCSVSeparator;
};
#endif // VTAPESETTINGS_H

View file

@ -48,9 +48,8 @@ class VContainer;
* //Need delete dialog here because parser in dialog don't allow use correct separator for parsing here.
* //Don't know why.
* delete dialog;
* Calculator *cal = new Calculator();
* QScopedPointer<Calculator> cal(new Calculator());
* result = cal->EvalFormula(data->PlainVariables(), formula);
* delete cal;//Here can be memory leak, but dialog already check this formula and probability very low.
* }
*/
class Calculator:public qmu::QmuFormulaBase

View file

@ -68,6 +68,11 @@ VCurveVariable::~VCurveVariable()
//---------------------------------------------------------------------------------------------------------------------
bool VCurveVariable::Filter(quint32 id)
{
if (id == NULL_ID)
{
return false;
}
if (d->parentId != NULL_ID)//Do not check if value zero
{// Not all curves have parents. Only those who was created after cutting the parent curve.
return d->id == id || d->parentId == id;

View file

@ -91,7 +91,7 @@ void VLineAngle::SetValue(const VPointF *p1, const VPointF *p2)
SCASSERT(p1 != nullptr);
SCASSERT(p2 != nullptr);
//Correct angle. Try avoid results like 6,7563e-15.
const qreal angle = qFloor(QLineF(p1->toQPointF(), p2->toQPointF()).angle() * 100000.) / 100000.;
const qreal angle = qFloor(QLineF(*p1, *p2).angle() * 100000.) / 100000.;
VInternalVariable::SetValue(angle);
}

View file

@ -85,7 +85,7 @@ void VLengthLine::SetValue(const VPointF *p1, const VPointF *p2)
SCASSERT(p1 != nullptr);
SCASSERT(p2 != nullptr);
VInternalVariable::SetValue(FromPixel(QLineF(p1->toQPointF(), p2->toQPointF()).length(), d->patternUnit));
VInternalVariable::SetValue(FromPixel(QLineF(*p1, *p2).length(), d->patternUnit));
}
//---------------------------------------------------------------------------------------------------------------------

View file

@ -56,7 +56,7 @@ Q_LOGGING_CATEGORY(vCon, "v.container")
quint32 VContainer::_id = NULL_ID;
qreal VContainer::_size = 50;
qreal VContainer::_height = 176;
QSet<const QString> VContainer::uniqueNames = QSet<const QString>();
QSet<QString> VContainer::uniqueNames = QSet<QString>();
//---------------------------------------------------------------------------------------------------------------------
/**
@ -557,6 +557,14 @@ bool VContainer::IsUnique(const QString &name)
return (!uniqueNames.contains(name) && !builInFunctions.contains(name));
}
//---------------------------------------------------------------------------------------------------------------------
QStringList VContainer::AllUniqueNames()
{
QStringList names = builInFunctions;
names.append(uniqueNames.toList());
return names;
}
//---------------------------------------------------------------------------------------------------------------------
const Unit *VContainer::GetPatternUnit() const
{

View file

@ -167,6 +167,7 @@ public:
const QHash<QString, qreal *> PlainVariables() const;
static bool IsUnique(const QString &name);
static QStringList AllUniqueNames();
const Unit *GetPatternUnit() const;
const VTranslateVars *GetTrVars() const;
@ -178,7 +179,7 @@ private:
static quint32 _id;
static qreal _size;
static qreal _height;
static QSet<const QString> uniqueNames;
static QSet<QString> uniqueNames;
QSharedDataPointer<VContainerData> d;

View file

@ -371,7 +371,7 @@ QVector<QPointF> VDetail::ContourPoints(const VContainer *data) const
case (Tool::NodePoint):
{
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(at(i).getId());
points.append(point->toQPointF());
points.append(*point);
}
break;
case (Tool::NodeArc):
@ -412,7 +412,7 @@ QVector<QPointF> VDetail::SeamAllowancePoints(const VContainer *data) const
case (Tool::NodePoint):
{
const QSharedPointer<VPointF> point = data->GeometricObject<VPointF>(at(i).getId());
QPointF pEkv = point->toQPointF();
QPointF pEkv = *point;
pEkv.setX(pEkv.x()+at(i).getMx());
pEkv.setY(pEkv.y()+at(i).getMy());
pointsEkv.append(pEkv);
@ -555,14 +555,14 @@ QPointF VDetail::StartSegment(const VContainer *data, const int &i, bool reverse
{
if (at(CountNode()-1).getTypeTool() == Tool::NodePoint)
{
begin = data->GeometricObject<VPointF>(at(CountNode()-1).getId())->toQPointF();
begin = *data->GeometricObject<VPointF>(at(CountNode()-1).getId());
}
}
else
{
if (at(i-1).getTypeTool() == Tool::NodePoint)
{
begin = data->GeometricObject<VPointF>(at(i-1).getId())->toQPointF();
begin = *data->GeometricObject<VPointF>(at(i-1).getId());
}
}
}
@ -592,14 +592,14 @@ QPointF VDetail::EndSegment(const VContainer *data, const int &i, bool reverse)
{
if (at(0).getTypeTool() == Tool::NodePoint)
{
end = data->GeometricObject<VPointF>(at(0).getId())->toQPointF();
end = *data->GeometricObject<VPointF>(at(0).getId());
}
}
else
{
if (at(i+1).getTypeTool() == Tool::NodePoint)
{
end = data->GeometricObject<VPointF>(at(i+1).getId())->toQPointF();
end = *data->GeometricObject<VPointF>(at(i+1).getId());
}
}
}

View file

@ -32,7 +32,9 @@
#include "../vmisc/vabstractapplication.h"
#include "../vmisc/vsettings.h"
#include "vtranslatevars.h"
#include <QDebug>
#include <QtNumeric>
//VFormula
//---------------------------------------------------------------------------------------------------------------------
@ -43,8 +45,14 @@ VFormula::VFormula()
//---------------------------------------------------------------------------------------------------------------------
VFormula::VFormula(const QString &formula, const VContainer *container)
:formula(qApp->TrVars()->FormulaToUser(formula)), value(QString(tr("Error"))), checkZero(true), data(container),
toolId(NULL_ID), postfix(QString()), _error(true), dValue(0)
: formula(qApp->TrVars()->FormulaToUser(formula, qApp->Settings()->GetOsSeparator())),
value(QString(tr("Error"))),
checkZero(true),
data(container),
toolId(NULL_ID),
postfix(QString()),
_error(true),
dValue(0)
{
this->formula.replace("\n", " ");// Replace line return with spaces for calc if exist
Eval();
@ -114,7 +122,7 @@ void VFormula::SetFormula(const QString &value, FormulaType type)
{
if (type == FormulaType::ToUser)
{
formula = qApp->TrVars()->FormulaToUser(value);
formula = qApp->TrVars()->FormulaToUser(value, qApp->Settings()->GetOsSeparator());
}
else
{
@ -226,23 +234,31 @@ void VFormula::Eval()
{
try
{
Calculator *cal = new Calculator();
QScopedPointer<Calculator> cal(new Calculator());
QString expression = qApp->TrVars()->FormulaFromUser(formula, qApp->Settings()->GetOsSeparator());
const qreal result = cal->EvalFormula(data->PlainVariables(), expression);
delete cal;
//if result equal 0
if (checkZero && qFuzzyIsNull(result))
if (qIsInf(result) || qIsNaN(result))
{
value = QString("0");
value = QString(tr("Error"));
_error = true;
dValue = 0;
}
else
{
dValue = result;
value = QString(qApp->LocaleToString(result) + " " + postfix);
_error = false;
//if result equal 0
if (checkZero && qFuzzyIsNull(result))
{
value = QString("0");
_error = true;
dValue = 0;
}
else
{
dValue = result;
value = QString(qApp->LocaleToString(result) + " " + postfix);
_error = false;
}
}
}
catch (qmu::QmuParserError &e)

View file

@ -40,7 +40,7 @@
using namespace qmu;
//---------------------------------------------------------------------------------------------------------------------
VTranslateVars::VTranslateVars(bool osSeparator)
VTranslateVars::VTranslateVars()
:VTranslateMeasurements(),
PMSystemNames(QMap<QString, QmuTranslation>()),
PMSystemAuthors(QMap<QString, QmuTranslation>()),
@ -48,8 +48,7 @@ VTranslateVars::VTranslateVars(bool osSeparator)
variables(QMap<QString, QmuTranslation>()),
functions(QMap<QString, QmuTranslation>()),
postfixOperators(QMap<QString, QmuTranslation>()),
stDescriptions(QMap<QString, QmuTranslation>()),
osSeparator(osSeparator)
stDescriptions(QMap<QString, QmuTranslation>())
{
InitPatternMakingSystems();
InitVariables();
@ -804,7 +803,7 @@ QString VTranslateVars::TryFormulaFromUser(const QString &formula, bool osSepara
* @param formula expression that need translate
* @return translated expression
*/
QString VTranslateVars::FormulaToUser(const QString &formula) const
QString VTranslateVars::FormulaToUser(const QString &formula, bool osSeparator) const
{
if (formula.isEmpty())
{

View file

@ -34,7 +34,7 @@
class VTranslateVars : public VTranslateMeasurements
{
public:
explicit VTranslateVars(bool osSeparator);
explicit VTranslateVars();
virtual ~VTranslateVars() Q_DECL_OVERRIDE;
bool VariablesFromUser(QString &newFormula, int position, const QString &token, int &bias) const;
@ -55,7 +55,7 @@ public:
QString FormulaFromUser(const QString &formula, bool osSeparator) const;
QString TryFormulaFromUser(const QString &formula, bool osSeparator) const;
QString FormulaToUser(const QString &formula) const;
QString FormulaToUser(const QString &formula, bool osSeparator) const;
virtual void Retranslate() Q_DECL_OVERRIDE;
@ -68,7 +68,6 @@ private:
QMap<QString, qmu::QmuTranslation> functions;
QMap<QString, qmu::QmuTranslation> postfixOperators;
QMap<QString, qmu::QmuTranslation> stDescriptions;
bool osSeparator;
void InitPatternMakingSystems();
void InitVariables();

View file

@ -37,7 +37,8 @@ HEADERS += \
$$PWD/tools/dialogpointofintersectioncurves.h \
$$PWD/tools/dialogcubicbezier.h \
$$PWD/tools/dialogcubicbezierpath.h \
$$PWD/tools/dialoggroup.h
$$PWD/tools/dialoggroup.h \
$$PWD/tools/dialogrotation.h
SOURCES += \
$$PWD/tools/dialogalongline.cpp \
@ -74,7 +75,8 @@ SOURCES += \
$$PWD/tools/dialogpointofintersectioncurves.cpp \
$$PWD/tools/dialogcubicbezier.cpp \
$$PWD/tools/dialogcubicbezierpath.cpp \
$$PWD/tools/dialoggroup.cpp
$$PWD/tools/dialoggroup.cpp \
$$PWD/tools/dialogrotation.cpp
FORMS += \
$$PWD/tools/dialogalongline.ui \
@ -110,4 +112,5 @@ FORMS += \
$$PWD/tools/dialogpointofintersectioncurves.ui \
$$PWD/tools/dialogcubicbezier.ui \
$$PWD/tools/dialogcubicbezierpath.ui \
$$PWD/tools/dialoggroup.ui
$$PWD/tools/dialoggroup.ui \
$$PWD/tools/dialogrotation.ui

View file

@ -298,7 +298,7 @@ void DialogEditWrongFormula::showEvent(QShowEvent *event)
//---------------------------------------------------------------------------------------------------------------------
void DialogEditWrongFormula::SetFormula(const QString &value)
{
formula = qApp->TrVars()->FormulaToUser(value);
formula = qApp->TrVars()->FormulaToUser(value, qApp->Settings()->GetOsSeparator());
// increase height if needed. TODO : see if I can get the max number of caracters in one line
// of this PlainTextEdit to change 80 to this value
if (formula.length() > 80)

View file

@ -61,6 +61,7 @@
#include "dialogs/tools/dialogpointfromarcandtangent.h"
#include "dialogs/tools/dialogtruedarts.h"
#include "dialogs/tools/dialoggroup.h"
#include "dialogs/tools/dialogrotation.h"
#include "dialogs/support/dialogeditwrongformula.h"
#include "dialogs/support/dialogundo.h"

View file

@ -250,7 +250,7 @@ void DialogAlongLine::SetFirstPointId(const quint32 &value)
*/
void DialogAlongLine::SetFormula(const QString &value)
{
formula = qApp->TrVars()->FormulaToUser(value);
formula = qApp->TrVars()->FormulaToUser(value, qApp->Settings()->GetOsSeparator());
// increase height if needed.
if (formula.length() > 80)
{

View file

@ -135,7 +135,7 @@ void DialogArc::SetCenter(const quint32 &value)
*/
void DialogArc::SetF2(const QString &value)
{
f2 = qApp->TrVars()->FormulaToUser(value);
f2 = qApp->TrVars()->FormulaToUser(value, qApp->Settings()->GetOsSeparator());
// increase height if needed.
if (f2.length() > 80)
{
@ -169,7 +169,7 @@ void DialogArc::SetColor(const QString &value)
*/
void DialogArc::SetF1(const QString &value)
{
f1 = qApp->TrVars()->FormulaToUser(value);
f1 = qApp->TrVars()->FormulaToUser(value, qApp->Settings()->GetOsSeparator());
// increase height if needed.
if (f1.length() > 80)
{
@ -191,7 +191,7 @@ void DialogArc::SetF1(const QString &value)
*/
void DialogArc::SetRadius(const QString &value)
{
radius = qApp->TrVars()->FormulaToUser(value);
radius = qApp->TrVars()->FormulaToUser(value, qApp->Settings()->GetOsSeparator());
// increase height if needed.
if (radius.length() > 80)
{

View file

@ -116,7 +116,7 @@ QString DialogArcWithLength::GetRadius() const
//---------------------------------------------------------------------------------------------------------------------
void DialogArcWithLength::SetRadius(const QString &value)
{
radius = qApp->TrVars()->FormulaToUser(value);
radius = qApp->TrVars()->FormulaToUser(value, qApp->Settings()->GetOsSeparator());
// increase height if needed.
if (radius.length() > 80)
{
@ -139,7 +139,7 @@ QString DialogArcWithLength::GetF1() const
void DialogArcWithLength::SetF1(const QString &value)
{
f1 = qApp->TrVars()->FormulaToUser(value);
f1 = qApp->TrVars()->FormulaToUser(value, qApp->Settings()->GetOsSeparator());
// increase height if needed.
if (f1.length() > 80)
{
@ -163,7 +163,7 @@ QString DialogArcWithLength::GetLength() const
//---------------------------------------------------------------------------------------------------------------------
void DialogArcWithLength::SetLength(const QString &value)
{
length = qApp->TrVars()->FormulaToUser(value);
length = qApp->TrVars()->FormulaToUser(value, qApp->Settings()->GetOsSeparator());
// increase height if needed.
if (length.length() > 80)
{

Some files were not shown because too many files have changed in this diff Show more