Merge branch 'master' into sketcherMoveColorsToPrefs

This commit is contained in:
abdullahtahiriyo
2021-10-13 10:01:30 +02:00
committed by GitHub
24 changed files with 854 additions and 640 deletions

View File

@@ -64,7 +64,8 @@ def cutComponentwithPlane(archObject, cutPlane, sideFace):
obj.ViewObject.ShapeColor = (1.00,0.00,0.00)
obj.ViewObject.Transparency = 75
if "Additions" in archObject.Object.PropertiesList:
return ArchCommands.removeComponents(obj,archObject.Object)
ArchCommands.removeComponents(obj,archObject.Object)
return None
else:
cutObj = FreeCAD.ActiveDocument.addObject("Part::Cut","CutPlane")
cutObj.Base = archObject.Object

View File

@@ -878,8 +878,7 @@ class _Wall(ArchComponent.Component):
else:
cuts2.append(sh)
offset += (obj.BlockLength.Value + obj.Joint.Value)
else:
offset -= (edge.Length - obj.Joint.Value)
offset -= (edge.Length - obj.Joint.Value)
if isinstance(bplates,list):
bplates = bplates[0]

View File

@@ -128,7 +128,6 @@ class ArchWorkbench(FreeCADGui.Workbench):
import RebarTools
except Exception:
del self.archtools[3] # remove "Arch_Rebar_Submenu"
pass
else:
class RebarGroupCommand:
def GetCommands(self):

View File

@@ -509,7 +509,7 @@ def make_radial_dimension_obj(edge_object, index=1, mode="radius",
def make_angular_dimension(center=App.Vector(0, 0, 0),
angles=[0, 90],
angles=None, # If None, set to [0,90]
dim_line=App.Vector(10, 10, 0), normal=None):
"""Create an angular dimension from the given center and angles.
@@ -555,6 +555,10 @@ def make_angular_dimension(center=App.Vector(0, 0, 0),
_name = "make_angular_dimension"
utils.print_header(_name, "Angular dimension")
# Prevent later modification of a default parameter by using a placeholder
if angles is None:
angles = [0, 90]
found, doc = utils.find_doc(App.activeDocument())
if not found:
_err(translate("draft","No active document. Aborting."))

View File

@@ -1,5 +1,6 @@
# ***************************************************************************
# * (c) 2020 Eliud Cabrera Castillo <e.cabrera-castillo@tum.de> *
# * Copyright (c) 2020 Eliud Cabrera Castillo <e.cabrera-castillo@tum.de> *
# * Copyright (c) 2021 FreeCAD Developers *
# * *
# * This file is part of the FreeCAD CAx development system. *
# * *
@@ -40,7 +41,6 @@ Or load it as a module and use the defined function.
## \addtogroup drafttests
# @{
import datetime
import os
import FreeCAD as App
import Part
@@ -66,17 +66,7 @@ def _set_text(text_list, position):
def _create_frame(doc=None):
"""Draw a frame with information on the version of the software.
It includes the date created, the version, the release type,
and the branch.
Parameters
----------
doc: App::Document, optional
It defaults to `None`, which then defaults to the current
active document, or creates a new document.
"""
"""Draw a frame with information on the version of the software."""
if not doc:
doc = App.activeDocument()
if not doc:
@@ -101,10 +91,10 @@ def _create_frame(doc=None):
record.ViewObject.FontSize = 400
record.ViewObject.TextColor = (0.0, 0.0, 0.0)
p1 = Vector(-1000, -3500, 0)
p2 = Vector(20000, -3500, 0)
p3 = Vector(20000, 8500, 0)
p4 = Vector(-1000, 8500, 0)
p1 = Vector(-1000, -4000, 0)
p2 = Vector(17000, -4000, 0)
p3 = Vector(17000, 8000, 0)
p4 = Vector(-1000, 8000, 0)
poly = Part.makePolygon([p1, p2, p3, p4, p1])
frame = doc.addObject("Part::Feature", "Frame")
@@ -112,199 +102,135 @@ def _create_frame(doc=None):
def _create_objects(doc=None,
font_file="/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"):
"""Create the objects of the test file.
Parameters
----------
doc: App::Document, optional
It defaults to `None`, which then defaults to the current
active document, or creates a new document.
"""
font_file=None,
hatch_file=None,
hatch_name=None):
"""Create the objects of the test file."""
if not doc:
doc = App.activeDocument()
if not doc:
doc = App.newDocument()
# Line, wire, and fillet
# Drafting ##############################################################
# Line
_msg(16 * "-")
_msg("Line")
Draft.make_line(Vector(0, 0, 0), Vector(500, 500, 0))
t_xpos = -50
t_ypos = -200
_set_text(["Line"], Vector(t_xpos, t_ypos, 0))
_set_text(["Line"], Vector(0, -200, 0))
# Wire
_msg(16 * "-")
_msg("Wire")
Draft.make_wire([Vector(500, 0, 0),
Vector(1000, 500, 0),
Vector(1000, 1000, 0)])
t_xpos += 500
_set_text(["Wire"], Vector(t_xpos, t_ypos, 0))
Draft.make_wire([Vector(1000, 0, 0),
Vector(1500, 250, 0),
Vector(1500, 500, 0)])
_set_text(["Wire"], Vector(1000, -200, 0))
# Fillet
_msg(16 * "-")
_msg("Fillet")
line_h_1 = Draft.make_line(Vector(1500, 0, 0), Vector(1500, 500, 0))
line_h_2 = Draft.make_line(Vector(1500, 500, 0), Vector(2000, 500, 0))
line_1 = Draft.make_line(Vector(2000, 0, 0), Vector(2000, 500, 0))
line_2 = Draft.make_line(Vector(2000, 500, 0), Vector(2500, 500, 0))
if App.GuiUp:
line_h_1.ViewObject.DrawStyle = "Dotted"
line_h_2.ViewObject.DrawStyle = "Dotted"
line_1.ViewObject.DrawStyle = "Dotted"
line_2.ViewObject.DrawStyle = "Dotted"
doc.recompute()
Draft.make_fillet([line_1, line_2], 400)
_set_text(["Fillet"], Vector(2000, -200, 0))
Draft.make_fillet([line_h_1, line_h_2], 400)
t_xpos += 900
_set_text(["Fillet"], Vector(t_xpos, t_ypos, 0))
# Circle, arc, arc by 3 points
_msg(16 * "-")
_msg("Circle")
circle = Draft.make_circle(350)
circle.Placement.Base = Vector(2500, 500, 0)
t_xpos += 1050
_set_text(["Circle"], Vector(t_xpos, t_ypos, 0))
# Circular arc
_msg(16 * "-")
_msg("Circular arc")
arc = Draft.make_circle(350, startangle=0, endangle=100)
arc.Placement.Base = Vector(3200, 500, 0)
t_xpos += 800
_set_text(["Circular arc"], Vector(t_xpos, t_ypos, 0))
arc = Draft.make_circle(250, startangle=90, endangle=270)
arc.Placement.Base = Vector(3250, 250, 0)
_set_text(["Circular arc"], Vector(3000, -200, 0))
# Circular arc 3 points
_msg(16 * "-")
_msg("Circular arc 3 points")
Draft.make_arc_3points([Vector(4600, 0, 0),
Vector(4600, 800, 0),
Vector(4000, 1000, 0)])
t_xpos += 600
_set_text(["Circular arc 3 points"], Vector(t_xpos, t_ypos, 0))
Draft.make_arc_3points([Vector(4250, 0, 0),
Vector(4000, 250, 0),
Vector(4250, 500, 0)])
_set_text(["Circular arc 3 points"], Vector(4000, -200, 0))
# Ellipse, polygon, rectangle
# Circle
_msg(16 * "-")
_msg("Circle")
circle = Draft.make_circle(250)
circle.Placement.Base = Vector(5250, 250, 0)
_set_text(["Circle"], Vector(5000, -200, 0))
# Ellipse
_msg(16 * "-")
_msg("Ellipse")
ellipse = Draft.make_ellipse(500, 300)
ellipse.Placement.Base = Vector(5500, 250, 0)
t_xpos += 1600
_set_text(["Ellipse"], Vector(t_xpos, t_ypos, 0))
ellipse = Draft.make_ellipse(250, 150)
ellipse.Placement.Base = Vector(6250, 150, 0)
_set_text(["Ellipse"], Vector(6000, -200, 0))
# Rectangle
_msg(16 * "-")
_msg("Rectangle")
rectangle = Draft.make_rectangle(500, 300, 0)
rectangle.Placement.Base = Vector(7000, 0, 0)
_set_text(["Rectangle"], Vector(7000, -200, 0))
# Polygon
_msg(16 * "-")
_msg("Polygon")
polygon = Draft.make_polygon(5, 250)
polygon.Placement.Base = Vector(6500, 500, 0)
t_xpos += 950
_set_text(["Polygon"], Vector(t_xpos, t_ypos, 0))
_msg(16 * "-")
_msg("Rectangle")
rectangle = Draft.make_rectangle(500, 1000, 0)
rectangle.Placement.Base = Vector(7000, 0, 0)
t_xpos += 650
_set_text(["Rectangle"], Vector(t_xpos, t_ypos, 0))
# Text
_msg(16 * "-")
_msg("Text")
text = Draft.make_text(["Testing", "text"], Vector(7700, 500, 0))
if App.GuiUp:
text.ViewObject.FontSize = 100
t_xpos += 700
_set_text(["Text"], Vector(t_xpos, t_ypos, 0))
# Linear dimension
_msg(16 * "-")
_msg("Linear dimension")
line = Draft.make_wire([Vector(8700, 200, 0),
Vector(8700, 1200, 0)])
dimension = Draft.make_linear_dimension(Vector(8600, 200, 0),
Vector(8600, 1000, 0),
Vector(8400, 750, 0))
if App.GuiUp:
dimension.ViewObject.ArrowSize = 15
dimension.ViewObject.ExtLines = 1000
dimension.ViewObject.ExtOvershoot = 100
dimension.ViewObject.DimOvershoot = 50
dimension.ViewObject.FontSize = 100
dimension.ViewObject.ShowUnit = False
doc.recompute()
dim_obj = Draft.make_linear_dimension_obj(line, 1, 2,
Vector(9000, 750, 0))
if App.GuiUp:
dim_obj.ViewObject.ArrowSize = 15
dim_obj.ViewObject.ArrowType = "Arrow"
dim_obj.ViewObject.ExtLines = 100
dim_obj.ViewObject.ExtOvershoot = 100
dim_obj.ViewObject.DimOvershoot = 50
dim_obj.ViewObject.FontSize = 100
dim_obj.ViewObject.ShowUnit = False
t_xpos += 680
_set_text(["Dimension"], Vector(t_xpos, t_ypos, 0))
# Radius and diameter dimension
_msg(16 * "-")
_msg("Radius and diameter dimension")
arc_h = Draft.make_circle(500, startangle=0, endangle=90)
arc_h.Placement.Base = Vector(9500, 0, 0)
doc.recompute()
dimension_r = Draft.make_radial_dimension_obj(arc_h, 1,
"radius",
Vector(9750, 200, 0))
if App.GuiUp:
dimension_r.ViewObject.ArrowSize = 15
dimension_r.ViewObject.FontSize = 100
dimension_r.ViewObject.ShowUnit = False
arc_h2 = Draft.make_circle(450, startangle=-120, endangle=80)
arc_h2.Placement.Base = Vector(10000, 1000, 0)
doc.recompute()
dimension_d = Draft.make_radial_dimension_obj(arc_h2, 1,
"diameter",
Vector(10750, 900, 0))
if App.GuiUp:
dimension_d.ViewObject.ArrowSize = 15
dimension_d.ViewObject.FontSize = 100
dimension_d.ViewObject.ShowUnit = False
t_xpos += 950
_set_text(["Radius dimension",
"Diameter dimension"], Vector(t_xpos, t_ypos, 0))
# Angular dimension
_msg(16 * "-")
_msg("Angular dimension")
Draft.make_line(Vector(10500, 300, 0), Vector(11500, 1000, 0))
Draft.make_line(Vector(10500, 300, 0), Vector(11500, 0, 0))
angle1 = -20
angle2 = 40
dimension_a = Draft.make_angular_dimension(Vector(10500, 300, 0),
[angle1, angle2],
Vector(11500, 300, 0))
if App.GuiUp:
dimension_a.ViewObject.ArrowSize = 15
dimension_a.ViewObject.FontSize = 100
t_xpos += 1700
_set_text(["Angle dimension"], Vector(t_xpos, t_ypos, 0))
polygon.Placement.Base = Vector(8250, 250, 0)
_set_text(["Polygon"], Vector(8000, -200, 0))
# BSpline
_msg(16 * "-")
_msg("BSpline")
Draft.make_bspline([Vector(12500, 0, 0),
Vector(12500, 500, 0),
Vector(13000, 500, 0),
Vector(13000, 1000, 0)])
t_xpos += 1500
_set_text(["BSpline"], Vector(t_xpos, t_ypos, 0))
Draft.make_bspline([Vector(9000, 0, 0),
Vector(9100, 200, 0),
Vector(9400, 300, 0),
Vector(9500, 500, 0)])
_set_text(["BSpline"], Vector(9000, -200, 0))
# Cubic bezier
_msg(16 * "-")
_msg("Cubic bezier")
Draft.make_bezcurve([Vector(10000, 0, 0),
Vector(10000, 500, 0),
Vector(10500, 0, 0),
Vector(10500, 500, 0)], degree=3)
_set_text(["Cubic bezier"], Vector(10000, -200, 0))
# N-degree bezier
_msg(16 * "-")
_msg("N-degree bezier")
Draft.make_bezcurve([Vector (11000, 0, 0),
Vector (11100, 400, 0),
Vector (11250, 250, 0),
Vector (11400, 100, 0),
Vector (11500, 500, 0)])
_set_text(["N-degree bezier"], Vector(11000, -200, 0))
# Point
_msg(16 * "-")
_msg("Point")
point = Draft.make_point(13500, 500, 0)
point = Draft.make_point(12000, 0, 0)
if App.GuiUp:
point.ViewObject.PointSize = 10
t_xpos += 900
_set_text(["Point"], Vector(t_xpos, t_ypos, 0))
_set_text(["Point"], Vector(12000, -200, 0))
# Facebinder
_msg(16 * "-")
_msg("Facebinder")
box = doc.addObject("Part::Box", "Box")
box.Length = 200
box.Width = 500
box.Height = 100
box.Placement.Base = Vector(13000, 0, 0)
if App.GuiUp:
box.ViewObject.Visibility = False
facebinder = Draft.make_facebinder([(box, ("Face1", "Face3", "Face6"))])
facebinder.Extrusion = 10
_set_text(["Facebinder"], Vector(13000, -200, 0))
# Shapestring
_msg(16 * "-")
@@ -313,268 +239,347 @@ def _create_objects(doc=None,
shape_string = Draft.make_shapestring("Testing",
font_file,
100)
shape_string.Placement.Base = Vector(14000, 500)
shape_string.Placement.Base = Vector(14000, 0)
except Exception:
_wrn("Shapestring could not be created")
_wrn("Possible cause: the font file may not exist")
_wrn(font_file)
rect = Draft.make_rectangle(500, 100)
rect.Placement.Base = Vector(14000, 500)
t_xpos += 600
_set_text(["Shapestring"], Vector(t_xpos, t_ypos, 0))
_set_text(["Shapestring"], Vector(14000, -200, 0))
# Facebinder
# Hatch
_msg(16 * "-")
_msg("Facebinder")
box = doc.addObject("Part::Box", "Cube")
box.Length = 200
box.Width = 500
box.Height = 100
box.Placement.Base = Vector(15000, 0, 0)
_msg("Hatch")
rectangle = Draft.make_rectangle(500, 300, 0)
rectangle.Placement.Base = Vector(15000, 0, 0)
rectangle.MakeFace = True
if App.GuiUp:
box.ViewObject.Visibility = False
rectangle.ViewObject.Visibility = False
try:
Draft.make_hatch(rectangle,
hatch_file,
hatch_name,
scale=10,
rotation=45)
except Exception:
_wrn("Hatch could not be created")
_wrn("Possible cause: the hatch file may not exist")
_wrn(hatch_file)
_set_text(["Hatch"], Vector(15000, -200, 0))
facebinder = Draft.make_facebinder([(box, ("Face1", "Face3", "Face6"))])
facebinder.Extrusion = 10
t_xpos += 780
_set_text(["Facebinder"], Vector(t_xpos, t_ypos, 0))
# Annotation ############################################################
# Cubic bezier curve, n-degree bezier curve
# Text
_msg(16 * "-")
_msg("Cubic bezier")
Draft.make_bezcurve([Vector(15500, 0, 0),
Vector(15578, 485, 0),
Vector(15879, 154, 0),
Vector(15975, 400, 0),
Vector(16070, 668, 0),
Vector(16423, 925, 0),
Vector(16500, 500, 0)], degree=3)
t_xpos += 680
_set_text(["Cubic bezier"], Vector(t_xpos, t_ypos, 0))
_msg("Text")
text = Draft.make_text(["Testing", "text"], Vector(0, 2100, 0))
if App.GuiUp:
text.ViewObject.FontSize = 100
_set_text(["Text"], Vector(0, 1800, 0))
# Linear dimension
_msg(16 * "-")
_msg("N-degree bezier")
Draft.make_bezcurve([Vector(16500, 0, 0),
Vector(17000, 500, 0),
Vector(17500, 500, 0),
Vector(17500, 1000, 0),
Vector(17000, 1000, 0),
Vector(17063, 1256, 0),
Vector(17732, 1227, 0),
Vector(17790, 720, 0),
Vector(17702, 242, 0)])
t_xpos += 1200
_set_text(["n-Bezier"], Vector(t_xpos, t_ypos, 0))
_msg("Linear dimension")
dimension = Draft.make_linear_dimension(Vector(1500, 2000, 0),
Vector(1500, 2400, 0),
Vector(1000, 2200, 0))
if App.GuiUp:
dimension.ViewObject.ArrowSize = 15
dimension.ViewObject.ExtLines = 0
dimension.ViewObject.ExtOvershoot = 50
dimension.ViewObject.DimOvershoot = 25
dimension.ViewObject.FontSize = 50
dimension.ViewObject.Decimals = 1
dimension.ViewObject.ShowUnit = False
line = Draft.make_wire([Vector(1500, 2600, 0),
Vector(1500, 3000, 0)])
doc.recompute()
dimension = Draft.make_linear_dimension_obj(line, 1, 2,
Vector(1000, 2800, 0))
if App.GuiUp:
dimension.ViewObject.ArrowSize = 15
dimension.ViewObject.ArrowType = "Arrow"
dimension.ViewObject.ExtLines = -50
dimension.ViewObject.ExtOvershoot = 50
dimension.ViewObject.DimOvershoot = 25
dimension.ViewObject.FontSize = 50
dimension.ViewObject.Decimals = 1
dimension.ViewObject.ShowUnit = False
_set_text(["Dimension"], Vector(1000, 1800, 0))
# Radius and diameter dimension
_msg(16 * "-")
_msg("Radius and diameter dimension")
circle = Draft.make_circle(200)
circle.Placement.Base = Vector(2200, 2200, 0)
circle.MakeFace = False
doc.recompute()
dimension = Draft.make_radial_dimension_obj(circle,
1,
"radius",
Vector(2300, 2300, 0))
if App.GuiUp:
dimension.ViewObject.ArrowSize = 15
dimension.ViewObject.FontSize = 50
dimension.ViewObject.Decimals = 1
dimension.ViewObject.ShowUnit = False
circle = Draft.make_circle(200)
circle.Placement.Base = Vector(2200, 2800, 0)
circle.MakeFace = False
doc.recompute()
dimension = Draft.make_radial_dimension_obj(circle,
1,
"diameter",
Vector(2300, 2900, 0))
if App.GuiUp:
dimension.ViewObject.ArrowSize = 15
dimension.ViewObject.FontSize = 50
dimension.ViewObject.Decimals = 1
dimension.ViewObject.ShowUnit = False
_set_text(["Radius dimension",
"Diameter dimension"], Vector(2000, 1800, 0))
# Angular dimension
_msg(16 * "-")
_msg("Angular dimension")
Draft.make_line(Vector(3000, 2000, 0), Vector(3500, 2000, 0))
Draft.make_line(Vector(3000, 2000, 0), Vector(3500, 2500, 0))
dimension = Draft.make_angular_dimension(Vector(3000, 2000, 0),
[0, 45],
Vector(3250, 2250, 0))
if App.GuiUp:
dimension.ViewObject.ArrowSize = 15
dimension.ViewObject.FontSize = 50
dimension.ViewObject.Decimals = 1
_set_text(["Angle dimension"], Vector(3000, 1800, 0))
# Label
_msg(16 * "-")
_msg("Label")
place = App.Placement(Vector(18500, 500, 0), App.Rotation())
label = Draft.make_label(target_point=Vector(18000, 0, 0),
place = App.Placement(Vector(4250, 2250, 0), App.Rotation())
label = Draft.make_label(target_point=Vector(4000, 2000, 0),
placement=place,
custom_text="Example label",
distance=-250)
distance=-100)
label.Text = "Testing"
if App.GuiUp:
label.ViewObject.ArrowSize = 15
label.ViewObject.TextSize = 100
label.ViewObject.TextSize = 50
doc.recompute()
t_xpos += 1200
_set_text(["Label"], Vector(t_xpos, t_ypos, 0))
_set_text(["Label"], Vector(4000, 1800, 0))
# Orthogonal array and orthogonal link array
# Array #################################################################
# Orthogonal array
_msg(16 * "-")
_msg("Orthogonal array")
rect_h = Draft.make_rectangle(500, 500)
rect_h.Placement.Base = Vector(1500, 2500, 0)
rectangle = Draft.make_rectangle(100, 50)
rectangle.Placement.Base = Vector(0, 4000, 0)
if App.GuiUp:
rect_h.ViewObject.Visibility = False
Draft.make_ortho_array(rect_h,
Vector(600, 0, 0),
Vector(0, 600, 0),
rectangle.ViewObject.Visibility = False
Draft.make_ortho_array(rectangle,
Vector(200, 0, 0),
Vector(0, 150, 0),
Vector(0, 0, 0),
3, 2, 1,
3,
2,
1,
use_link=False)
t_xpos = 1700
t_ypos = 2200
_set_text(["Array"], Vector(t_xpos, t_ypos, 0))
rect_h_2 = Draft.make_rectangle(500, 100)
rect_h_2.Placement.Base = Vector(1500, 5000, 0)
if App.GuiUp:
rect_h_2.ViewObject.Visibility = False
_set_text(["Orthogonal array"], Vector(0, 3800, 0))
# Orthogonal link array
_msg(16 * "-")
_msg("Orthogonal link array")
Draft.make_ortho_array(rect_h_2,
Vector(800, 0, 0),
Vector(0, 500, 0),
rectangle = Draft.make_rectangle(50, 50)
rectangle.Placement.Base = Vector(1000, 4000, 0)
if App.GuiUp:
rectangle.ViewObject.Visibility = False
Draft.make_ortho_array(rectangle,
Vector(200, 0, 0),
Vector(0, 150, 0),
Vector(0, 0, 0),
2, 4, 1,
3,
2,
1,
use_link=True)
t_ypos += 2600
_set_text(["Link array"], Vector(t_xpos, t_ypos, 0))
_set_text(["Orthogonal link array"], Vector(1000, 3800, 0))
# Polar array and polar link array
# Polar array
_msg(16 * "-")
_msg("Polar array")
wire_h = Draft.make_wire([Vector(5500, 3000, 0),
Vector(6000, 3500, 0),
Vector(6000, 3200, 0),
Vector(5800, 3200, 0)])
wire = Draft.make_wire([Vector(2000, 4050, 0),
Vector(2000, 4000, 0),
Vector(2100, 4000, 0)])
if App.GuiUp:
wire_h.ViewObject.Visibility = False
Draft.make_polar_array(wire_h,
8,
200,
Vector(5000, 3000, 0),
wire.ViewObject.Visibility = False
Draft.make_polar_array(wire,
4,
90,
Vector(2000, 4250, 0),
use_link=False)
_set_text(["Polar array"], Vector(2000, 3800, 0))
t_xpos = 4600
t_ypos = 2200
_set_text(["Polar array"], Vector(t_xpos, t_ypos, 0))
# Polar link array
_msg(16 * "-")
_msg("Polar link array")
wire_h_2 = Draft.make_wire([Vector(5500, 6000, 0),
Vector(6000, 6000, 0),
Vector(5800, 5700, 0),
Vector(5800, 5750, 0)])
wire = Draft.make_wire([Vector(3000, 4050, 0),
Vector(3000, 4000, 0),
Vector(3050, 4000, 0)])
if App.GuiUp:
wire_h_2.ViewObject.Visibility = False
Draft.make_polar_array(wire_h_2,
8,
200,
Vector(5000, 6000, 0),
wire.ViewObject.Visibility = False
Draft.make_polar_array(wire,
4,
90,
Vector(3000, 4250, 0),
use_link=True)
t_ypos += 3200
_set_text(["Polar link array"], Vector(t_xpos, t_ypos, 0))
_set_text(["Polar link array"], Vector(3000, 3800, 0))
# Circular array and circular link array
# Circular array
_msg(16 * "-")
_msg("Circular array")
poly_h = Draft.make_polygon(5, 200)
poly_h.Placement.Base = Vector(8000, 3000, 0)
polygon = Draft.make_polygon(5, 30)
polygon.Placement.Base = Vector(4250, 4250, 0)
if App.GuiUp:
poly_h.ViewObject.Visibility = False
Draft.make_circular_array(poly_h,
500, 600,
polygon.ViewObject.Visibility = False
Draft.make_circular_array(polygon,
110,
100,
3,
1,
Vector(0, 0, 1),
Vector(0, 0, 0),
use_link=False)
t_xpos = 7700
t_ypos = 1700
_set_text(["Circular array"], Vector(t_xpos, t_ypos, 0))
_set_text(["Circular array"], Vector(4000, 3800, 0))
# Circular link array
_msg(16 * "-")
_msg("Circular link array")
poly_h_2 = Draft.make_polygon(6, 150)
poly_h_2.Placement.Base = Vector(8000, 6250, 0)
polygon = Draft.make_polygon(6, 30)
polygon.Placement.Base = Vector(5250, 4250, 0)
if App.GuiUp:
poly_h_2.ViewObject.Visibility = False
Draft.make_circular_array(poly_h_2,
550, 450,
polygon.ViewObject.Visibility = False
Draft.make_circular_array(polygon,
110,
100,
3,
1,
Vector(0, 0, 1),
Vector(0, 0, 0),
use_link=True)
t_ypos += 3100
_set_text(["Circular link array"], Vector(t_xpos, t_ypos, 0))
_set_text(["Circular link array"], Vector(5000, 3800, 0))
# Path array and path link array
# Path array
_msg(16 * "-")
_msg("Path array")
poly_h = Draft.make_polygon(3, 250)
poly_h.Placement.Base = Vector(10000, 3000, 0)
polygon = Draft.make_polygon(3, 30)
polygon.Placement.Base = Vector(6000, 4000, 0)
if App.GuiUp:
poly_h.ViewObject.Visibility = False
bspline_path = Draft.make_bspline([Vector(10500, 2500, 0),
Vector(11000, 3000, 0),
Vector(11500, 3200, 0),
Vector(12000, 4000, 0)])
Draft.make_path_array(poly_h, bspline_path, 5,
use_link=False)
t_xpos = 10400
t_ypos = 2200
_set_text(["Path array"], Vector(t_xpos, t_ypos, 0))
polygon.ViewObject.Visibility = False
spline = Draft.make_bspline([Vector(6000, 4000, 0),
Vector(6100, 4200, 0),
Vector(6400, 4300, 0),
Vector(6500, 4500, 0)])
Draft.make_path_array(polygon, spline, 5, use_link=False)
_set_text(["Path array"], Vector(6000, 3800, 0))
# Path link array
_msg(16 * "-")
_msg("Path link array")
poly_h_2 = Draft.make_polygon(4, 200)
poly_h_2.Placement.Base = Vector(10000, 5000, 0)
polygon = Draft.make_polygon(4, 30)
polygon.Placement.Base = Vector(7000, 4000, 0)
if App.GuiUp:
poly_h_2.ViewObject.Visibility = False
bspline_path_2 = Draft.make_bspline([Vector(10500, 4500, 0),
Vector(11000, 6800, 0),
Vector(11500, 6000, 0),
Vector(12000, 5200, 0)])
Draft.make_path_array(poly_h_2, bspline_path_2, 6,
use_link=True)
t_ypos += 2000
_set_text(["Path link array"], Vector(t_xpos, t_ypos, 0))
polygon.ViewObject.Visibility = False
spline = Draft.make_bspline([Vector(7000, 4000, 0),
Vector(7100, 4200, 0),
Vector(7400, 4300, 0),
Vector(7500, 4500, 0)])
Draft.make_path_array(polygon, spline, 5, use_link=True)
_set_text(["Path link array"], Vector(7000, 3800, 0))
# Point array
_msg(16 * "-")
_msg("Point array")
poly_h = Draft.make_polygon(3, 250)
poly_h.Placement.Base = Vector(12500, 2500, 0)
point_1 = Draft.make_point(13000, 3000, 0)
point_2 = Draft.make_point(13000, 3500, 0)
point_3 = Draft.make_point(14000, 2500, 0)
point_4 = Draft.make_point(14000, 3000, 0)
polygon = Draft.make_polygon(3, 30)
polygon.Placement.Base = Vector(8000, 4000, 0)
point_1 = Draft.make_point(8030, 4030, 0)
point_2 = Draft.make_point(8030, 4250, 0)
point_3 = Draft.make_point(8470, 4250, 0)
point_4 = Draft.make_point(8470, 4470, 0)
add_list, delete_list = Draft.upgrade([point_1, point_2,
point_3, point_4])
compound = add_list[0]
if App.GuiUp:
compound.ViewObject.PointSize = 5
Draft.make_point_array(polygon, compound, use_link=False)
_set_text(["Point array"], Vector(8000, 3800, 0))
Draft.make_point_array(poly_h, compound)
t_xpos = 13000
t_ypos = 2200
_set_text(["Point array"], Vector(t_xpos, t_ypos, 0))
# Clone and mirror
# Point link array
_msg(16 * "-")
_msg("Clone")
wire_h = Draft.make_wire([Vector(15000, 2500, 0),
Vector(15200, 3000, 0),
Vector(15500, 2500, 0),
Vector(15200, 2300, 0)])
_msg("Point link array")
polygon = Draft.make_polygon(4, 30)
polygon.Placement.Base = Vector(9000, 4000, 0)
point_1 = Draft.make_point(9030, 4030, 0)
point_2 = Draft.make_point(9030, 4250, 0)
point_3 = Draft.make_point(9470, 4250, 0)
point_4 = Draft.make_point(9470, 4470, 0)
add_list, delete_list = Draft.upgrade([point_1, point_2,
point_3, point_4])
compound = add_list[0]
if App.GuiUp:
compound.ViewObject.PointSize = 5
Draft.make_point_array(polygon, compound, use_link=True)
_set_text(["Point link array"], Vector(9000, 3800, 0))
Draft.make_clone(wire_h, Vector(0, 1000, 0))
t_xpos = 15000
t_ypos = 2100
_set_text(["Clone"], Vector(t_xpos, t_ypos, 0))
# Miscellaneous #########################################################
# Mirror
_msg(16 * "-")
_msg("Mirror")
wire_h = Draft.make_wire([Vector(17000, 2500, 0),
Vector(16500, 4000, 0),
Vector(16000, 2700, 0),
Vector(16500, 2500, 0),
Vector(16700, 2700, 0)])
wire = Draft.make_wire([Vector(0, 6000, 0),
Vector(150, 6200, 0),
Vector(500, 6000, 0)])
Draft.mirror(wire,
Vector(0, 6250, 0),
Vector(500, 6250, 0))
_set_text(["Mirror"], Vector(0, 5800, 0))
Draft.mirror(wire_h,
Vector(17100, 2000, 0),
Vector(17100, 4000, 0))
t_xpos = 17000
t_ypos = 2200
_set_text(["Mirror"], Vector(t_xpos, t_ypos, 0))
# Clone
_msg(16 * "-")
_msg("Clone")
wire = Draft.make_wire([Vector(1000, 6000, 0),
Vector(1150, 6200, 0),
Vector(1500, 6000, 0)])
Draft.make_clone(wire, Vector(0, 300, 0))
_set_text(["Clone"], Vector(1000, 5800, 0))
# Shape2DView
_msg(16 * "-")
_msg("Shape2DView")
place = App.Placement(Vector(2000, 6000, 0),
App.Rotation(Vector(0, 0, 1), Vector(1, 2, 3)))
box = doc.addObject("Part::Box", "Box")
box.Length = 200
box.Width = 500
box.Height = 100
box.Placement = place
if App.GuiUp:
box.ViewObject.Visibility = False
Draft.make_shape2dview(box)
_set_text(["Shape2DView"], Vector(2000, 5800, 0))
# WorkingPlaneProxy
_msg(16 * "-")
_msg("WorkingPlaneProxy")
place = App.Placement(Vector(3250, 6250, 0), App.Rotation())
proxy = Draft.make_workingplaneproxy(place)
if App.GuiUp:
proxy.ViewObject.DisplaySize = 500
proxy.ViewObject.ArrowSize = 50
_set_text(["WorkingPlaneProxy"], Vector(3000, 5800, 0))
# Layer
_msg(16 * "-")
_msg("Layer")
layer = Draft.make_layer("Custom layer",
@@ -582,39 +587,24 @@ def _create_objects(doc=None,
shape_color=(0.56, 0.89, 0.56),
line_width=4,
transparency=50)
cube = doc.addObject('Part::Box')
cube.Length = 350
cube.Width = 300
cube.Height = 250
cube.Placement.Base = Vector(14000, 5500, 0)
cone = doc.addObject('Part::Cone')
cone.Radius1 = 400
cone.Height = 600
cone.Angle = 270
cone.Placement.Base = Vector(15000, 6000, 0)
sphere = doc.addObject('Part::Sphere')
sphere.Radius = 450
sphere.Angle1 = -45
sphere.Angle2 = 45
sphere.Angle3 = 300
sphere.Placement.Base = Vector(14000, 7000, 0)
layer.Proxy.addObject(layer, cube)
layer.Proxy.addObject(layer, cone)
box = doc.addObject("Part::Box", "Box")
box.Length = 200
box.Width = 500
box.Height = 100
box.Placement.Base = Vector(4000, 6000, 0)
sphere = doc.addObject("Part::Sphere", "Sphere")
sphere.Radius = 100
sphere.Placement.Base = Vector(4400, 6250, 0)
layer.Proxy.addObject(layer, box)
layer.Proxy.addObject(layer, sphere)
_set_text(["Layer"], Vector(4000, 5800, 0))
t_xpos = 14000
t_ypos = 5000
_set_text(["Layer"], Vector(t_xpos, t_ypos, 0))
doc.recompute()
def create_test_file(file_name="draft_test_objects",
file_path=os.environ["HOME"],
save=False,
font_file="/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"):
def create_test_file(font_file=App.getHomePath()+"data/Mod/TechDraw/Resources/fonts/osifont-lgpl3fe.ttf",
hatch_file=App.getHomePath()+"data/Mod/TechDraw/PAT/FCPAT.pat",
hatch_name="Horizontal5"):
"""Create a complete test file of Draft objects.
It draws a frame with information on the software used to create
@@ -622,63 +612,35 @@ def create_test_file(file_name="draft_test_objects",
Parameters
----------
file_name: str, optional
It defaults to `'draft_test_objects'`.
It is the name of the document that is created.
The `file_name` will be appended to `file_path`
to determine the actual path to save. The extension `.FCStd`
will be added automatically.
file_path: str, optional
It defaults to the value of `os.environ['HOME']`
which in Linux is usually `'/home/user'`.
If it is the empty string `''` it will use the value
returned by `App.getUserAppDataDir()`,
for example, `'/home/user/.FreeCAD/'`.
save: bool, optional
It defaults to `False`. If it is `True` the new document
will be saved to disk after creating all objects.
font_file: str, optional
It defaults to `'/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf'`.
It is the full path of a font in the system to be used
to create a `Draft ShapeString`.
If the font is not found, this object is not created.
It defaults to `App.getHomePath()+"data/Mod/TechDraw/Resources/fonts/osifont-lgpl3fe.ttf"`
It is the full path of a font file to be used to create a `Draft ShapeString`.
If the file is not found, this object is not created.
hatch_file: str, optional
It defaults to `App.getHomePath()+"data/Mod/TechDraw/PAT/FCPAT.pat"`
It is the full path of a PAT file to be used to create a `Draft Hatch`.
If the file is not found, this object is not created.
hatch_name: str, optional
It defaults to `"Horizontal5"`
It is the name of a hatch pattern in the hatch_file.
Returns
-------
App::Document
A reference to the test document that was created.
To Do
-----
Find a reliable way of getting a default font to be able to create
the `Draft ShapeString`.
"""
doc = App.newDocument(file_name)
_msg(16 * "-")
_msg("Filename: {}".format(file_name))
_msg("If the units tests fail, this script may fail as well")
doc = App.newDocument()
_create_frame(doc=doc)
_create_objects(doc=doc, font_file=font_file)
_create_objects(doc=doc, font_file=font_file, hatch_file=hatch_file, hatch_name=hatch_name)
if App.GuiUp:
Gui.runCommand("Std_ViewFitAll")
# Export
if not file_path:
file_path = App.getUserAppDataDir()
out_name = os.path.join(file_path, file_name + ".FCStd")
doc.FileName = out_name
if save:
doc.save()
_msg(16 * "-")
_msg("Saved: {}".format(out_name))
Gui.Selection.clearSelection()
return doc

View File

@@ -141,37 +141,37 @@ FaceUnwrapper::FaceUnwrapper(const TopoDS_Face& face)
if (triangulation.IsNull())
throw std::runtime_error("null triangulation in face construction");
Standard_Integer numNodes = triangulation->NbNodes();
Standard_Integer numTriangles = triangulation->NbTriangles();
// compute uv coordinates
if (triangulation->HasUVNodes())
{
const TColgp_Array1OfPnt2d &_uv_nodes = triangulation->UVNodes();
this->uv_nodes.resize(triangulation->NbNodes(), 2);
this->uv_nodes.resize(numNodes, 2);
i = 0;
for (Standard_Integer index = _uv_nodes.Lower(); index <= _uv_nodes.Upper(); ++index)
for (Standard_Integer index = 1; index <= numNodes; ++index)
{
const gp_Pnt2d& _uv_node = _uv_nodes.Value(index);
const gp_Pnt2d& _uv_node = triangulation->UVNode(index);
this->uv_nodes.row(i) << _uv_node.X(), _uv_node.Y();
i++;
}
}
//
const TColgp_Array1OfPnt &_nodes = triangulation->Nodes();
this->xyz_nodes.resize(triangulation->NbNodes(), 3);
this->xyz_nodes.resize(numNodes, 3);
i = 0;
for (Standard_Integer index = _nodes.Lower(); index <= _nodes.Upper(); ++index)
for (Standard_Integer index = 1; index <= numNodes; ++index)
{
gp_Pnt _node = _nodes.Value(index);
gp_Pnt _node = triangulation->Node(index);
this->xyz_nodes.row(i) << _node.X(), _node.Y(), _node.Z();
i++;
}
const Poly_Array1OfTriangle &_tris = triangulation->Triangles();
this->tris.resize(triangulation->NbTriangles(), 3);
this->tris.resize(numTriangles, 3);
i = 0;
for (Standard_Integer index = _tris.Lower(); index <= _tris.Upper(); ++index)
for (Standard_Integer index = 1; index <= numTriangles; ++index)
{
int n1, n2, n3;
Poly_Triangle _tri = _tris.Value(index);
const Poly_Triangle& _tri = triangulation->Triangle(index);
_tri.Get(n1, n2, n3);
this->tris.row(i) << n1-1, n2-1, n3-1;
i++;

View File

@@ -99,7 +99,6 @@ class CommandEditAttachment:
return False
if App.GuiUp:
global command_instance
import FreeCADGui as Gui
command_instance = CommandEditAttachment()
Gui.addCommand('Part_EditAttachment', command_instance)

View File

@@ -272,6 +272,7 @@ FaceColors::FaceColors(ViewProviderPartExt* vp, QWidget* parent)
d->ui->setupUi(this);
d->ui->groupBox->setTitle(QString::fromUtf8(vp->getObject()->Label.getValue()));
d->ui->colorButton->setDisabled(true);
d->ui->colorButton->setAllowTransparency(true);
FaceSelection* gate = new FaceSelection(d->vp->getObject());
Gui::Selection().addSelectionGate(gate);
@@ -354,10 +355,9 @@ void FaceColors::on_defaultButton_clicked()
void FaceColors::on_colorButton_changed()
{
if (!d->index.isEmpty()) {
float alpha = static_cast<float>(d->vp->Transparency.getValue())/100;
QColor c = d->ui->colorButton->color();
for (QSet<int>::iterator it = d->index.begin(); it != d->index.end(); ++it) {
d->perface[*it].set(c.redF(), c.greenF(), c.blueF(), alpha);
d->perface[*it].set(c.redF(), c.greenF(), c.blueF(), c.alphaF());
}
d->vp->DiffuseColor.setValues(d->perface);
}
@@ -380,7 +380,7 @@ void FaceColors::onSelectionChanged(const Gui::SelectionChanges& msg)
d->index.insert(index);
const App::Color& c = d->perface[index];
QColor color;
color.setRgbF(c.r,c.g,c.b);
color.setRgbF(c.r,c.g,c.b,c.a);
d->ui->colorButton->setColor(color);
selection_changed = true;
}

View File

@@ -1292,6 +1292,7 @@ public:
Sketcher::PointPos originpos, int nelements,
SketcherCopy::Op op)
: Mode(STATUS_SEEK_First)
, snapMode(SnapMode::Free)
, geoIdList(geoidlist)
, Origin()
, OriginGeoId(origingeoid)
@@ -1309,6 +1310,11 @@ public:
STATUS_End
};
enum class SnapMode {
Free,
Snap5Degree
};
virtual void activated(ViewProviderSketch *sketchgui)
{
setCursor(QPixmap(cursor_createcopy), 7, 7);
@@ -1319,15 +1325,29 @@ public:
virtual void mouseMove(Base::Vector2d onSketchPos)
{
if (Mode == STATUS_SEEK_First) {
if(QApplication::keyboardModifiers() == Qt::ControlModifier)
snapMode = SnapMode::Snap5Degree;
else
snapMode = SnapMode::Free;
float length = (onSketchPos - EditCurve[0]).Length();
float angle = (onSketchPos - EditCurve[0]).GetAngle(Base::Vector2d(1.f,0.f));
float angle = (onSketchPos - EditCurve[0]).Angle();
Base::Vector2d endpoint = onSketchPos;
if (snapMode == SnapMode::Snap5Degree) {
angle = round(angle / (M_PI/36)) * M_PI/36;
endpoint = EditCurve[0] + length * Base::Vector2d(cos(angle),sin(angle));
}
SbString text;
text.sprintf(" (%.1f, %.1fdeg)", length, angle * 180 / M_PI);
setPositionText(onSketchPos, text);
setPositionText(endpoint, text);
EditCurve[1] = onSketchPos;
EditCurve[1] = endpoint;
sketchgui->drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.0, 0.0), AutoConstraint::VERTEX)) {
if (seekAutoConstraint(sugConstr1, endpoint, Base::Vector2d(0.0, 0.0), AutoConstraint::VERTEX)) {
renderSuggestConstraintsCursor(sugConstr1);
return;
}
@@ -1335,10 +1355,9 @@ public:
applyCursor();
}
virtual bool pressButton(Base::Vector2d onSketchPos)
virtual bool pressButton(Base::Vector2d)
{
if (Mode == STATUS_SEEK_First) {
EditCurve[1] = onSketchPos;
sketchgui->drawEdit(EditCurve);
Mode = STATUS_End;
}
@@ -1401,6 +1420,7 @@ public:
}
protected:
SelectMode Mode;
SnapMode snapMode;
string geoIdList;
Base::Vector3d Origin;
int OriginGeoId;
@@ -1841,7 +1861,7 @@ public:
enum class SnapMode {
Free,
Snap10Degree
Snap5Degree
};
virtual void activated(ViewProviderSketch *sketchgui)
@@ -1856,17 +1876,17 @@ public:
if (Mode==STATUS_SEEK_First) {
if(QApplication::keyboardModifiers() == Qt::ControlModifier)
snapMode = SnapMode::Snap10Degree;
snapMode = SnapMode::Snap5Degree;
else
snapMode = SnapMode::Free;
float length = (onSketchPos - EditCurve[0]).Length();
float angle = (onSketchPos - EditCurve[0]).GetAngle(Base::Vector2d(1.f, 0.f));
float angle = (onSketchPos - EditCurve[0]).Angle();
Base::Vector2d endpoint = onSketchPos;
if (snapMode == SnapMode::Snap10Degree) {
angle = round(angle / (M_PI/18)) * M_PI/18;
if (snapMode == SnapMode::Snap5Degree) {
angle = round(angle / (M_PI/36)) * M_PI/36;
endpoint = EditCurve[0] + length * Base::Vector2d(cos(angle),sin(angle));
}

View File

@@ -982,6 +982,14 @@ void PropertySheet::getSpans(CellAddress address, int & rows, int & cols) const
}
}
App::CellAddress Spreadsheet::PropertySheet::getAnchor(App::CellAddress address) const
{
if (auto anchor = mergedCells.find(address); anchor != mergedCells.end())
return anchor->second;
else
return address;
}
bool PropertySheet::isMergedCell(CellAddress address) const
{
return mergedCells.find(address) != mergedCells.end();

View File

@@ -148,6 +148,8 @@ public:
void getSpans(App::CellAddress address, int &rows, int &cols) const;
App::CellAddress getAnchor(App::CellAddress address) const;
bool isMergedCell(App::CellAddress address) const;
bool isHidden(App::CellAddress address) const;

View File

@@ -1063,6 +1063,11 @@ bool Sheet::isMergedCell(CellAddress address) const
return cells.isMergedCell(address);
}
App::CellAddress Spreadsheet::Sheet::getAnchor(App::CellAddress address) const
{
return cells.getAnchor(address);
}
/**
* @brief Set column with of column \a col to \a width-
* @param col Index of column.

View File

@@ -110,6 +110,8 @@ public:
bool isMergedCell(App::CellAddress address) const;
App::CellAddress getAnchor(App::CellAddress address) const;
void setColumnWidth(int col, int width);
int getColumnWidth(int col) const;

View File

@@ -26,68 +26,58 @@
# include <QKeyEvent>
#endif
#include <QCoreApplication>
#include "LineEdit.h"
using namespace SpreadsheetGui;
LineEdit::LineEdit(QWidget *parent)
: Gui::ExpressionLineEdit(parent, false, true)
, current()
, deltaCol(0)
, deltaRow(0)
, lastKeyPressed(0)
{
setFocusPolicy(Qt::FocusPolicy::ClickFocus);
}
bool LineEdit::eventFilter(QObject* object, QEvent* event)
{
Q_UNUSED(object);
if (event && event->type() == QEvent::KeyPress) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Tab) {
// Special tab handling -- must be done via a QApplication event filter, otherwise the widget
// system will always grab the tab events
if (completerActive()) {
hideCompleter();
event->accept();
return true; // To make sure this tab press doesn't do anything else
}
else {
lastKeyPressed = keyEvent->key();
lastModifiers = keyEvent->modifiers();
}
}
}
return false; // We don't usually actually "handle" the tab event, we just keep track of it
}
bool LineEdit::event(QEvent *event)
{
if (event && event->type() == QEvent::KeyPress) {
if (event && event->type() == QEvent::FocusIn) {
qApp->installEventFilter(this);
}
else if (event && event->type() == QEvent::FocusOut) {
qApp->removeEventFilter(this);
if (lastKeyPressed)
Q_EMIT finishedWithKey(lastKeyPressed, lastModifiers);
lastKeyPressed = 0;
}
else if (event && event->type() == QEvent::KeyPress && !completerActive()) {
QKeyEvent * kevent = static_cast<QKeyEvent*>(event);
if (kevent->key() == Qt::Key_Tab) {
if (kevent->modifiers() == 0) {
deltaCol = 1;
deltaRow = 0;
Q_EMIT returnPressed();
return true;
}
}
else if (kevent->key() == Qt::Key_Backtab) {
if (kevent->modifiers() == Qt::ShiftModifier) {
deltaCol = -1;
deltaRow = 0;
Q_EMIT returnPressed();
return true;
}
}
else if (kevent->key() == Qt::Key_Enter || kevent->key() == Qt::Key_Return) {
if (kevent->modifiers() == 0) {
deltaCol = 0;
deltaRow = 1;
Q_EMIT returnPressed();
return true;
}
else if (kevent->modifiers() == Qt::ShiftModifier) {
deltaCol = 0;
deltaRow = -1;
Q_EMIT returnPressed();
return true;
}
}
lastKeyPressed = kevent->key();
lastModifiers = kevent->modifiers();
}
return Gui::ExpressionLineEdit::event(event);
}
void LineEdit::setIndex(QModelIndex _current)
{
current = _current;
}
QModelIndex LineEdit::next() const
{
const QAbstractItemModel * m = current.model();
return m->index(qMin(qMax(0, current.row() + deltaRow), m->rowCount() - 1 ),
qMin(qMax(0, current.column() + deltaCol), m->columnCount() - 1 ) );
}
#include "moc_LineEdit.cpp"

View File

@@ -36,13 +36,17 @@ public:
explicit LineEdit(QWidget *parent = 0);
bool event(QEvent *event);
void setIndex(QModelIndex _current);
QModelIndex next() const;
Q_SIGNALS:
void finishedWithKey(int key, Qt::KeyboardModifiers modifiers);
private:
QModelIndex current;
int deltaCol;
int deltaRow;
bool eventFilter(QObject* object, QEvent* event);
private:
int lastKeyPressed;
Qt::KeyboardModifiers lastModifiers;
};
}

View File

@@ -101,6 +101,7 @@ static std::pair<int, int> selectedMinMaxColumns(QModelIndexList list)
SheetTableView::SheetTableView(QWidget *parent)
: QTableView(parent)
, sheet(0)
, tabCounter(0)
{
setHorizontalHeader(new SheetViewHeader(this,Qt::Horizontal));
setVerticalHeader(new SheetViewHeader(this,Qt::Vertical));
@@ -319,7 +320,7 @@ void SheetTableView::insertColumnsAfter()
{
assert(sheet != 0);
const auto columns = selectionModel()->selectedColumns();
const auto & [min, max] = selectedMinMaxColumns(columns);
const auto& [min, max] = selectedMinMaxColumns(columns);
assert(max - min == columns.size() - 1);
Q_UNUSED(min)
@@ -345,7 +346,7 @@ void SheetTableView::removeColumns()
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Remove rows"));
for (std::vector<int>::const_iterator it = sortedColumns.begin(); it != sortedColumns.end(); ++it)
Gui::cmdAppObjectArgs(sheet, "removeColumns('%s', %d)",
columnName(*it).c_str(), 1);
columnName(*it).c_str(), 1);
Gui::Command::commitCommand();
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
}
@@ -365,7 +366,7 @@ void SheetTableView::updateCellSpan(CellAddress address)
setSpan(address.row(), address.col(), rows, cols);
}
void SheetTableView::setSheet(Sheet * _sheet)
void SheetTableView::setSheet(Sheet* _sheet)
{
sheet = _sheet;
cellSpanChangedConnection = sheet->cellSpanChanged.connect(bind(&SheetTableView::updateCellSpan, this, bp::_1));
@@ -399,57 +400,45 @@ void SheetTableView::setSheet(Sheet * _sheet)
}
void SheetTableView::commitData ( QWidget * editor )
void SheetTableView::commitData(QWidget* editor)
{
QTableView::commitData(editor);
}
bool SheetTableView::edit ( const QModelIndex & index, EditTrigger trigger, QEvent * event )
bool SheetTableView::edit(const QModelIndex& index, EditTrigger trigger, QEvent* event)
{
if (trigger & (QAbstractItemView::DoubleClicked | QAbstractItemView::AnyKeyPressed | QAbstractItemView::EditKeyPressed) )
if (trigger & (QAbstractItemView::DoubleClicked | QAbstractItemView::AnyKeyPressed | QAbstractItemView::EditKeyPressed))
currentEditIndex = index;
return QTableView::edit(index, trigger, event);
}
bool SheetTableView::event(QEvent *event)
bool SheetTableView::event(QEvent* event)
{
/* Catch key presses for navigating the table; Enter/Return (+Shift), and Tab (+Shift) */
if (event && event->type() == QEvent::KeyPress) {
QKeyEvent * kevent = static_cast<QKeyEvent*>(event);
if (kevent->key() == Qt::Key_Tab) {
QModelIndex c = currentIndex();
if (kevent->modifiers() == 0) {
setCurrentIndex(model()->index(c.row(), qMin(c.column() + 1, model()->columnCount() -1)));
return true;
}
}
else if (kevent->key() == Qt::Key_Backtab) {
QModelIndex c = currentIndex();
if (kevent->modifiers() == Qt::ShiftModifier) {
setCurrentIndex(model()->index(c.row(), qMax(c.column() - 1, 0)));
return true;
}
}
else if (kevent->key() == Qt::Key_Enter || kevent->key() == Qt::Key_Return) {
QModelIndex c = currentIndex();
if (kevent->modifiers() == 0) {
setCurrentIndex(model()->index(qMin(c.row() + 1, model()->rowCount() - 1), c.column()));
return true;
}
else if (kevent->modifiers() == Qt::ShiftModifier) {
setCurrentIndex(model()->index(qMax(c.row() - 1, 0), c.column()));
return true;
}
}
else if (kevent->key() == Qt::Key_Delete) {
if (event && event->type() == QEvent::KeyPress && this->hasFocus()) {
// If this widget has focus, look for keyboard events that represent movement shortcuts
// and handle them.
QKeyEvent* kevent = static_cast<QKeyEvent*>(event);
switch (kevent->key()) {
case Qt::Key_Return: [[fallthrough]];
case Qt::Key_Enter: [[fallthrough]];
case Qt::Key_Home: [[fallthrough]];
case Qt::Key_End: [[fallthrough]];
case Qt::Key_Left: [[fallthrough]];
case Qt::Key_Right: [[fallthrough]];
case Qt::Key_Up: [[fallthrough]];
case Qt::Key_Down: [[fallthrough]];
case Qt::Key_Tab: [[fallthrough]];
case Qt::Key_Backtab:
finishEditWithMove(kevent->key(), kevent->modifiers(), true);
return true;
// Also handle the delete key here:
case Qt::Key_Delete:
deleteSelection();
return true;
default:
break;
}
else if (kevent->matches(QKeySequence::Cut)) {
if (kevent->matches(QKeySequence::Cut)) {
cutSelection();
return true;
}
@@ -468,18 +457,19 @@ bool SheetTableView::event(QEvent *event)
kevent->modifiers() == Qt::ShiftModifier ||
kevent->modifiers() == Qt::KeypadModifier) {
switch (kevent->key()) {
case Qt::Key_Return:
case Qt::Key_Enter:
case Qt::Key_Delete:
case Qt::Key_Home:
case Qt::Key_End:
case Qt::Key_Backspace:
case Qt::Key_Left:
case Qt::Key_Right:
case Qt::Key_Up:
case Qt::Key_Down:
case Qt::Key_Return: [[fallthrough]];
case Qt::Key_Enter: [[fallthrough]];
case Qt::Key_Delete: [[fallthrough]];
case Qt::Key_Home: [[fallthrough]];
case Qt::Key_End: [[fallthrough]];
case Qt::Key_Backspace: [[fallthrough]];
case Qt::Key_Left: [[fallthrough]];
case Qt::Key_Right: [[fallthrough]];
case Qt::Key_Up: [[fallthrough]];
case Qt::Key_Down: [[fallthrough]];
case Qt::Key_Tab:
kevent->accept();
break;
default:
break;
}
@@ -614,13 +604,239 @@ void SheetTableView::pasteClipboard()
}
}
void SheetTableView::closeEditor(QWidget * editor, QAbstractItemDelegate::EndEditHint hint)
void SheetTableView::finishEditWithMove(int keyPressed, Qt::KeyboardModifiers modifiers, bool handleTabMotion)
{
SpreadsheetGui::LineEdit * le = qobject_cast<SpreadsheetGui::LineEdit*>(editor);
// A utility lambda for finding the beginning and ending of data regions
auto scanForRegionBoundary = [this](int& r, int& c, int dr, int dc) {
auto startAddress = CellAddress(r, c);
auto startCell = sheet->getCell(startAddress);
bool startedAtEmptyCell = startCell ? !startCell->isUsed() : true;
const int maxRow = this->model()->rowCount() - 1;
const int maxCol = this->model()->columnCount() - 1;
while (c + dc >= 0 && r + dr >= 0 && c + dc <= maxCol && r + dr <= maxRow) {
r += dr;
c += dc;
auto cell = sheet->getCell(CellAddress(r, c));
auto cellIsEmpty = cell ? !cell->isUsed() : true;
if (cellIsEmpty && !startedAtEmptyCell) {
// Don't stop at the empty cell, stop at the last non-empty cell
r -= dr;
c -= dc;
break;
}
else if (!cellIsEmpty && startedAtEmptyCell) {
break;
}
}
if (r == startAddress.row() && c == startAddress.col()) {
// Always move at least one cell:
r += dr;
c += dc;
}
r = std::max(0, std::min(r, maxRow));
c = std::max(0, std::min(c, maxCol));
};
currentEditIndex = QModelIndex();
int targetRow = currentIndex().row();
int targetColumn = currentIndex().column();
int colSpan;
int rowSpan;
sheet->getSpans(CellAddress(targetRow, targetColumn), rowSpan, colSpan);
switch (keyPressed) {
case Qt::Key_Return:
case Qt::Key_Enter:
if (modifiers == Qt::NoModifier) {
targetRow += rowSpan;
targetColumn -= tabCounter;
}
else if (modifiers == Qt::ShiftModifier) {
targetRow -= 1;
targetColumn -= tabCounter;
}
else {
// For an unrecognized modifier, just go down
targetRow += rowSpan;
}
tabCounter = 0;
break;
case Qt::Key_Home:
// Home: row 1, same column
// Ctrl-Home: row 1, column 1
targetRow = 0;
if (modifiers == Qt::ControlModifier)
targetColumn = 0;
tabCounter = 0;
break;
case Qt::Key_End:
{
// End should take you to the last occupied cell in the current column
// Ctrl-End takes you to the last cell in the sheet
auto usedCells = sheet->getCells()->getUsedCells();
for (const auto& cell : usedCells) {
if (modifiers == Qt::NoModifier) {
if (cell.col() == targetColumn)
targetRow = std::max(targetRow, cell.row());
}
else if (modifiers == Qt::ControlModifier) {
targetRow = std::max(targetRow, cell.row());
targetColumn = std::max(targetColumn, cell.col());
}
}
tabCounter = 0;
break;
}
case Qt::Key_Left:
if (targetColumn == 0)
break; // Nothing to do, we're already in the first column
if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier)
targetColumn--;
else if (modifiers == Qt::ControlModifier ||
modifiers == (Qt::ControlModifier | Qt::ShiftModifier))
scanForRegionBoundary(targetRow, targetColumn, 0, -1);
else
targetColumn--; //Unrecognized modifier combination: default to just moving one cell
tabCounter = 0;
break;
case Qt::Key_Right:
if (targetColumn >= this->model()->columnCount() - 1)
break; // Nothing to do, we're already in the last column
if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier)
targetColumn += colSpan;
else if (modifiers == Qt::ControlModifier ||
modifiers == (Qt::ControlModifier | Qt::ShiftModifier))
scanForRegionBoundary(targetRow, targetColumn, 0, 1);
else
targetColumn += colSpan; //Unrecognized modifier combination: default to just moving one cell
tabCounter = 0;
break;
case Qt::Key_Up:
if (targetRow == 0)
break; // Nothing to do, we're already in the first column
if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier)
targetRow--;
else if (modifiers == Qt::ControlModifier ||
modifiers == (Qt::ControlModifier | Qt::ShiftModifier))
scanForRegionBoundary(targetRow, targetColumn, -1, 0);
else
targetRow--; //Unrecognized modifier combination: default to just moving one cell
tabCounter = 0;
break;
case Qt::Key_Down:
if (targetRow >= this->model()->rowCount() - 1)
break; // Nothing to do, we're already in the last row
if (modifiers == Qt::NoModifier || modifiers == Qt::ShiftModifier)
targetRow += rowSpan;
else if (modifiers == Qt::ControlModifier ||
modifiers == (Qt::ControlModifier | Qt::ShiftModifier))
scanForRegionBoundary(targetRow, targetColumn, 1, 0);
else
targetRow += rowSpan; //Unrecognized modifier combination: default to just moving one cell
tabCounter = 0;
break;
case Qt::Key_Tab:
if (modifiers == Qt::NoModifier) {
tabCounter++;
if (handleTabMotion)
targetColumn += colSpan;
}
else if (modifiers == Qt::ShiftModifier) {
tabCounter = 0;
if (handleTabMotion)
targetColumn--;
}
break;
case Qt::Key_Backtab:
if (modifiers == Qt::NoModifier) {
targetColumn--;
}
tabCounter = 0;
break;
default:
break;
}
if (this->sheet->isMergedCell(CellAddress(targetRow, targetColumn))) {
auto anchor = this->sheet->getAnchor(CellAddress(targetRow, targetColumn));
targetRow = anchor.row();
targetColumn = anchor.col();
}
// Overflow/underflow protection:
const int maxRow = this->model()->rowCount() - 1;
const int maxCol = this->model()->columnCount() - 1;
targetRow = std::max(0, std::min(targetRow, maxRow));
targetColumn = std::max(0, std::min(targetColumn, maxCol));
if (!(modifiers & Qt::ShiftModifier) || keyPressed == Qt::Key_Tab || keyPressed == Qt::Key_Enter || keyPressed == Qt::Key_Return) {
// We have to use this method so that Ctrl-modifier combinations don't result in multiple selection
this->selectionModel()->setCurrentIndex(model()->index(targetRow, targetColumn),
QItemSelectionModel::ClearAndSelect);
}
else if (modifiers & Qt::ShiftModifier) {
// With shift down, this motion becomes a block selection command, rather than just simple motion:
ModifyBlockSelection(targetRow, targetColumn);
}
}
void SheetTableView::ModifyBlockSelection(int targetRow, int targetCol)
{
int startingRow = currentIndex().row();
int startingCol = currentIndex().column();
// Get the current block selection size:
auto selection = this->selectionModel()->selection();
for (const auto& range : selection) {
if (range.contains(currentIndex())) {
// This range contains the current cell, so it's the one we're going to modify (assuming we're at one of the corners)
int rangeMinRow = range.top();
int rangeMaxRow = range.bottom();
int rangeMinCol = range.left();
int rangeMaxCol = range.right();
if ((startingRow == rangeMinRow || startingRow == rangeMaxRow) &&
(startingCol == rangeMinCol || startingCol == rangeMaxCol)) {
if (range.contains(model()->index(targetRow, targetCol))) {
// If the range already contains the target cell, then we're making the range smaller
if (startingRow == rangeMinRow)
rangeMinRow = targetRow;
if (startingRow == rangeMaxRow)
rangeMaxRow = targetRow;
if (startingCol == rangeMinCol)
rangeMinCol = targetCol;
if (startingCol == rangeMaxCol)
rangeMaxCol = targetCol;
}
else {
// We're making the range bigger
rangeMinRow = std::min(rangeMinRow, targetRow);
rangeMaxRow = std::max(rangeMaxRow, targetRow);
rangeMinCol = std::min(rangeMinCol, targetCol);
rangeMaxCol = std::max(rangeMaxCol, targetCol);
}
QItemSelection oldRange(range.topLeft(), range.bottomRight());
this->selectionModel()->select(oldRange, QItemSelectionModel::Deselect);
QItemSelection newRange(model()->index(rangeMinRow, rangeMinCol), model()->index(rangeMaxRow, rangeMaxCol));
this->selectionModel()->select(newRange, QItemSelectionModel::Select);
}
break;
}
}
this->selectionModel()->setCurrentIndex(model()->index(targetRow, targetCol), QItemSelectionModel::Current);
}
void SheetTableView::closeEditor(QWidget * editor, QAbstractItemDelegate::EndEditHint hint)
{
QTableView::closeEditor(editor, hint);
setCurrentIndex(le->next());
}
void SheetTableView::mousePressEvent(QMouseEvent* event)
{
tabCounter = 0;
QTableView::mousePressEvent(event);
}
void SheetTableView::edit ( const QModelIndex & index )

View File

@@ -62,6 +62,9 @@ public:
void copySelection();
void cutSelection();
void pasteClipboard();
void finishEditWithMove(int keyPressed, Qt::KeyboardModifiers modifiers, bool handleTabMotion = false);
void ModifyBlockSelection(int targetRow, int targetColumn);
protected Q_SLOTS:
void commitData(QWidget *editor);
@@ -77,9 +80,11 @@ protected:
bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event);
bool event(QEvent *event);
void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint);
void mousePressEvent(QMouseEvent* event);
QModelIndex currentEditIndex;
Spreadsheet::Sheet * sheet;
int tabCounter;
boost::signals2::scoped_connection cellSpanChangedConnection;
};

View File

@@ -46,29 +46,13 @@ QWidget *SpreadsheetDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &,
const QModelIndex &index) const
{
Q_UNUSED(index)
SpreadsheetGui::LineEdit *editor = new SpreadsheetGui::LineEdit(parent);
editor->setIndex(index);
editor->setDocumentObject(sheet);
connect(editor, SIGNAL(returnPressed()), this, SLOT(commitAndCloseEditor()));
connect(editor, &SpreadsheetGui::LineEdit::finishedWithKey, this, &SpreadsheetDelegate::on_editorFinishedWithKey);
return editor;
}
void SpreadsheetDelegate::commitAndCloseEditor()
{
Gui::ExpressionLineEdit *editor = qobject_cast<Gui::ExpressionLineEdit *>(sender());
if (editor->completerActive()) {
editor->hideCompleter();
return;
}
// See https://forum.freecadweb.org/viewtopic.php?f=3&t=41694
// It looks like the slot commitAndCloseEditor() is not needed any more and even
// causes a crash when doing so because the LineEdit is still accessed after its destruction.
//Q_EMIT commitData(editor);
//Q_EMIT closeEditor(editor);
}
void SpreadsheetDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
@@ -89,6 +73,11 @@ void SpreadsheetDelegate::setModelData(QWidget *editor,
}
}
void SpreadsheetDelegate::on_editorFinishedWithKey(int key, Qt::KeyboardModifiers modifiers)
{
Q_EMIT finishedWithKey(key, modifiers);
}
QSize SpreadsheetDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
{
Q_UNUSED(option);

View File

@@ -45,8 +45,10 @@ public:
const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
Q_SIGNALS:
void finishedWithKey(int key, Qt::KeyboardModifiers modifiers);
private Q_SLOTS:
void commitAndCloseEditor();
void on_editorFinishedWithKey(int key, Qt::KeyboardModifiers modifiers);
private:
Spreadsheet::Sheet * sheet;
};

View File

@@ -98,9 +98,12 @@ SheetView::SheetView(Gui::Document *pcDocument, App::DocumentObject *docObj, QWi
connect(ui->cells->verticalHeader(), SIGNAL(sectionResized ( int, int, int ) ),
this, SLOT(rowResized(int, int, int)));
connect(ui->cellContent, SIGNAL(returnPressed()), this, SLOT( editingFinished() ));
connect(ui->cellAlias, SIGNAL(returnPressed()), this, SLOT( editingFinished() ));
connect(ui->cellAlias, SIGNAL(textEdited(QString)), this, SLOT(aliasChanged(QString)));
connect(delegate, &SpreadsheetDelegate::finishedWithKey, this, &SheetView::editingFinishedWithKey);
connect(ui->cellContent, &LineEdit::finishedWithKey, this, [this](int, Qt::KeyboardModifiers) {confirmContentChanged(ui->cellContent->text()); });
connect(ui->cellContent, &LineEdit::returnPressed, this, [this]() {confirmContentChanged(ui->cellContent->text()); });
connect(ui->cellAlias, &LineEdit::finishedWithKey, this, [this](int, Qt::KeyboardModifiers) {confirmAliasChanged(ui->cellAlias->text()); });
connect(ui->cellAlias, &LineEdit::returnPressed, this, [this]() {confirmAliasChanged(ui->cellAlias->text()); });
connect(ui->cellAlias, &LineEdit::textEdited, this, &SheetView::aliasChanged);
columnWidthChangedConnection = sheet->columnWidthChanged.connect(bind(&SheetView::resizeColumn, this, bp::_1, bp::_2));
rowHeightChangedConnection = sheet->rowHeightChanged.connect(bind(&SheetView::resizeRow, this, bp::_1, bp::_2));
@@ -215,20 +218,6 @@ void SheetView::setCurrentCell(QString str)
updateAliasLine();
}
void SheetView::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Delete) {
if (event->modifiers() == 0) {
//model()->setData(currentIndex(), QVariant(), Qt::EditRole);
}
else if (event->modifiers() == Qt::ControlModifier) {
//model()->setData(currentIndex(), QVariant(), Qt::EditRole);
}
}
else
Gui::MDIView::keyPressEvent(event);
}
void SheetView::updateContentLine()
{
QModelIndex i = ui->cells->currentIndex();
@@ -238,7 +227,6 @@ void SheetView::updateContentLine()
if (const auto * cell = sheet->getCell(CellAddress(i.row(), i.column())))
(void)cell->getStringContent(str);
ui->cellContent->setText(QString::fromUtf8(str.c_str()));
ui->cellContent->setIndex(i);
ui->cellContent->setEnabled(true);
// Update completer model; for the time being, we do this by setting the document object of the input line.
@@ -255,7 +243,6 @@ void SheetView::updateAliasLine()
if (const auto * cell = sheet->getCell(CellAddress(i.row(), i.column())))
(void)cell->getAlias(str);
ui->cellAlias->setText(QString::fromUtf8(str.c_str()));
ui->cellAlias->setIndex(i);
ui->cellAlias->setEnabled(true);
// Update completer model; for the time being, we do this by setting the document object of the input line.
@@ -322,51 +309,53 @@ void SheetView::resizeRow(int col, int newSize)
ui->cells->setRowHeight(col, newSize);
}
void SheetView::editingFinished()
void SheetView::editingFinishedWithKey(int key, Qt::KeyboardModifiers modifiers)
{
if (ui->cellContent->completerActive()) {
ui->cellContent->hideCompleter();
return;
}
if (ui->cellAlias->completerActive()) {
ui->cellAlias->hideCompleter();
return;
}
QModelIndex i = ui->cells->currentIndex();
if (i.isValid()) {
QString str = ui->cellAlias->text();
bool aliasOkay = true;
if (str.length()!= 0 && !sheet->isValidAlias(Base::Tools::toStdString(str))){
aliasOkay = false;
}
ui->cellAlias->setDocumentObject(sheet);
ui->cells->model()->setData(i, QVariant(ui->cellContent->text()), Qt::EditRole);
ui->cells->finishEditWithMove(key, modifiers);
}
}
if (const auto * cell = sheet->getCell(CellAddress(i.row(), i.column()))){
if (!aliasOkay){
//do not show error message if failure to set new alias is because it is already the same string
std::string current_alias;
(void)cell->getAlias(current_alias);
if (str != QString::fromUtf8(current_alias.c_str())){
Base::Console().Error("Unable to set alias: %s\n", Base::Tools::toStdString(str).c_str());
}
} else {
std::string address = CellAddress(i.row(), i.column()).toString();
Gui::cmdAppObjectArgs(sheet, "setAlias('%s', '%s')",
address, str.toStdString());
Gui::cmdAppDocument(sheet->getDocument(), "recompute()");
void SheetView::confirmAliasChanged(const QString& text)
{
bool aliasOkay = true;
ui->cellAlias->setDocumentObject(sheet);
if (text.length() != 0 && !sheet->isValidAlias(Base::Tools::toStdString(text))) {
aliasOkay = false;
}
QModelIndex i = ui->cells->currentIndex();
if (const auto* cell = sheet->getCell(CellAddress(i.row(), i.column()))) {
if (!aliasOkay) {
//do not show error message if failure to set new alias is because it is already the same string
std::string current_alias;
(void)cell->getAlias(current_alias);
if (text != QString::fromUtf8(current_alias.c_str())) {
Base::Console().Error("Unable to set alias: %s\n", Base::Tools::toStdString(text).c_str());
}
}
ui->cells->setCurrentIndex(ui->cellContent->next());
ui->cells->setFocus();
else {
std::string address = CellAddress(i.row(), i.column()).toString();
Gui::cmdAppObjectArgs(sheet, "setAlias('%s', '%s')",
address, text.toStdString());
Gui::cmdAppDocument(sheet->getDocument(), "recompute()");
ui->cells->setFocus();
}
}
}
void SheetView::confirmContentChanged(const QString& text)
{
QModelIndex i = ui->cells->currentIndex();
ui->cells->model()->setData(i, QVariant(text), Qt::EditRole);
ui->cells->setFocus();
}
void SheetView::aliasChanged(const QString& text)
{
// check live the input and highlight if the user input invalid characters

View File

@@ -82,8 +82,10 @@ public:
virtual void deleteSelf();
protected Q_SLOTS:
void editingFinished();
void editingFinishedWithKey(int key, Qt::KeyboardModifiers modifiers);
void confirmAliasChanged(const QString& text);
void aliasChanged(const QString& text);
void confirmContentChanged(const QString& text);
void currentChanged( const QModelIndex & current, const QModelIndex & previous );
void columnResized(int col, int oldSize, int newSize);
void rowResized(int row, int oldSize, int newSize);
@@ -94,7 +96,6 @@ protected:
void updateContentLine();
void updateAliasLine();
void setCurrentCell(QString str);
void keyPressEvent(QKeyEvent *event);
void resizeColumn(int col, int newSize);
void resizeRow(int col, int newSize);