1 /****************************************************************************
2 **
3 ** This file is part of the LibreCAD project, a 2D CAD program
4 **
5 ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
6 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
7 **
8 **
9 ** This file may be distributed and/or modified under the terms of the
10 ** GNU General Public License version 2 as published by the Free Software
11 ** Foundation and appearing in the file gpl-2.0.txt included in the
12 ** packaging of this file.
13 **
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ** GNU General Public License for more details.
18 **
19 ** You should have received a copy of the GNU General Public License
20 ** along with this program; if not, write to the Free Software
21 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 **
23 ** This copyright notice MUST APPEAR in all copies of the script!
24 **
25 **********************************************************************/
26 #include <QContextMenuEvent>
27 #include <QToolBar>
28 
29 #include "qg_snaptoolbar.h"
30 #include "rs_settings.h"
31 #include "qg_actionhandler.h"
32 #include "lc_actiongroupmanager.h"
33 
34 /*
35  *  Constructs a QG_CadToolBarSnap as a child of 'parent', with the
36  *  name 'name' and widget flags set to 'f'.
37  */
QG_SnapToolBar(QWidget * parent,QG_ActionHandler * ah,LC_ActionGroupManager * agm)38 QG_SnapToolBar::QG_SnapToolBar(QWidget* parent, QG_ActionHandler* ah, LC_ActionGroupManager* agm)
39 	: QToolBar(parent)
40     , actionHandler(ah)
41 {
42 
43     auto action = new QAction(tr("Exclusive Snap Mode"), agm->snap_extras);
44     action->setIcon(QIcon(":/icons/exclusive.svg"));
45     action->setCheckable(true);
46     connect(action, SIGNAL(toggled(bool)),
47             agm, SLOT(toggleExclusiveSnapMode(bool)));
48     action->setObjectName("ExclusiveSnapMode");
49     addAction(action);
50 
51     snapFree = new QAction(QIcon(":/icons/snap_free.svg"), tr("Free Snap"), agm->snap_extras);
52     snapFree->setCheckable(true);
53     snapFree->setObjectName("SnapFree");
54     connect(snapFree, SIGNAL(triggered()), this, SLOT(actionTriggered()));
55     this->addAction(snapFree);
56     snapGrid = new QAction(QIcon(":/icons/snap_grid.svg"), tr("Snap on grid"), agm->snap);
57     snapGrid->setObjectName("SnapGrid");
58     snapGrid->setCheckable(true);
59     connect(snapGrid, SIGNAL(triggered()), this, SLOT(actionTriggered()));
60     this->addAction(snapGrid);
61     snapEnd = new QAction(QIcon(":/icons/snap_endpoints.svg"), tr("Snap on Endpoints"), agm->snap);
62     snapEnd->setObjectName("SnapEnd");
63     snapEnd->setCheckable(true);
64     connect(snapEnd, SIGNAL(triggered()), this, SLOT(actionTriggered()));
65     this->addAction(snapEnd);
66     snapOnEntity = new QAction(QIcon(":/icons/snap_entity.svg"), tr("Snap on Entity"), agm->snap);
67     snapOnEntity->setObjectName("SnapEntity");
68     snapOnEntity->setCheckable(true);
69     connect(snapOnEntity, SIGNAL(triggered()), this, SLOT(actionTriggered()));
70     this->addAction(snapOnEntity);
71     snapCenter = new QAction(QIcon(":/icons/snap_center.svg"), tr("Snap Center"), agm->snap);
72     snapCenter->setObjectName("SnapCenter");
73     snapCenter->setCheckable(true);
74     connect(snapCenter, SIGNAL(triggered()), this, SLOT(actionTriggered()));
75     this->addAction(snapCenter);
76     snapMiddle = new QAction(QIcon(":/icons/snap_middle.svg"), tr("Snap Middle"), agm->snap);
77     snapMiddle->setObjectName("SnapMiddle");
78     snapMiddle->setCheckable(true);
79     connect(snapMiddle, SIGNAL(triggered()), this, SLOT(actionTriggered()));
80     this->addAction(snapMiddle);
81     snapDistance = new QAction(QIcon(":/icons/snap_distance.svg"), tr("Snap Distance"), agm->snap);
82     snapDistance->setObjectName("SnapDistance");
83     snapDistance ->setCheckable(true);
84     connect(snapDistance, SIGNAL(triggered()), this, SLOT(actionTriggered()));
85     this->addAction(snapDistance);
86     snapIntersection = new QAction(QIcon(":/icons/snap_intersection.svg"), tr("Snap Intersection"), agm->snap);
87     snapIntersection->setObjectName("SnapIntersection");
88     snapIntersection->setCheckable(true);
89     connect(snapIntersection, SIGNAL(triggered()), this, SLOT(actionTriggered()));
90 	this->addAction(snapIntersection);
91 
92     this->addSeparator();
93 
94     restrictHorizontal = new QAction(QIcon(":/icons/restr_hor.svg"),
95                                      tr("Restrict Horizontal"), agm->restriction);
96     restrictHorizontal->setObjectName("RestrictHorizontal");
97     restrictHorizontal->setCheckable(true);
98     connect(restrictHorizontal, SIGNAL(triggered()), this, SLOT(actionTriggered()));
99     this->addAction(restrictHorizontal);
100     restrictVertical = new QAction(QIcon(":/icons/restr_ver.svg"),
101                                    tr("Restrict Vertical"), agm->restriction);
102     restrictVertical->setObjectName("RestrictVertical");
103     restrictVertical->setCheckable(true);
104     connect(restrictVertical, SIGNAL(triggered()), this, SLOT(actionTriggered()));
105     this->addAction(restrictVertical);
106 
107     restrictOrthogonal = new QAction(QIcon(":/icons/restr_ortho.svg"),
108                                    tr("Restrict Orthogonal"), agm->restriction);
109     restrictOrthogonal->setObjectName("RestrictOrthogonal");
110     restrictOrthogonal->setCheckable(true);
111     connect(restrictOrthogonal, SIGNAL(triggered(bool)), this,
112             SLOT(slotRestrictOrthogonal(bool)));
113 	this->addAction(restrictOrthogonal);
114 
115     restrictNothing = new QAction(QIcon(":/extui/restrictnothing.png"),
116                                    tr("Restrict Nothing"), agm->restriction);
117     restrictNothing->setObjectName("RestrictNothing");
118     restrictNothing->setCheckable(true);
119     connect(restrictNothing, SIGNAL(triggered(bool)), this,
120             SLOT(slotRestrictNothing(bool)));
121 
122     this->addSeparator();
123     bRelZero = new QAction(QIcon(":/icons/set_rel_zero.svg"), tr("Set relative zero position"), agm->other);
124     bRelZero->setObjectName("SetRelativeZero");
125     bRelZero->setCheckable(false);
126     connect(bRelZero, SIGNAL(triggered()), actionHandler, SLOT(slotSetRelativeZero()));
127     //connect(bRelZero, SIGNAL(triggered()), this, SLOT(slotSetRelativeZero()));
128     this->addAction(bRelZero);
129     bLockRelZero = new QAction(QIcon(":/icons/lock_rel_zero.svg"), tr("Lock relative zero position"), agm->other);
130     bLockRelZero->setObjectName("LockRelativeZero");
131     bLockRelZero->setCheckable(true);
132     connect(bLockRelZero, SIGNAL(toggled(bool)),actionHandler, SLOT(slotLockRelativeZero(bool)));
133     this->addAction(bLockRelZero);
134     //restore snapMode from saved preferences
135     RS_SETTINGS->beginGroup("/Snap");
136     setSnaps( RS_SnapMode::fromInt( RS_SETTINGS->readNumEntry( "/SnapMode", 0)));
137     RS_SETTINGS->endGroup();
138 }
139 
saveSnapMode()140 void QG_SnapToolBar::saveSnapMode()
141 {
142     //@write default snap mode from prefrences.
143     unsigned int snapFlags {RS_SnapMode::toInt( getSnaps())};
144     RS_SETTINGS->beginGroup("/Snap");
145     RS_SETTINGS->writeEntry("/SnapMode",QString::number(snapFlags));
146     RS_SETTINGS->endGroup();
147     // no need to delete child widgets, Qt does it all for us
148 }
149 
setSnaps(RS_SnapMode const & s)150 void QG_SnapToolBar::setSnaps ( RS_SnapMode const& s )
151 {
152 	if(getSnaps()==s) return;
153     snapFree->setChecked(s.snapFree);
154     snapGrid->setChecked(s.snapGrid);
155     snapEnd->setChecked(s.snapEndpoint);
156     snapOnEntity->setChecked(s.snapOnEntity);
157     snapCenter->setChecked(s.snapCenter);
158     snapMiddle->setChecked(s.snapMiddle);
159     snapDistance->setChecked(s.snapDistance);
160     snapIntersection->setChecked(s.snapIntersection);
161     restrictHorizontal->setChecked(s.restriction==RS2::RestrictHorizontal ||  s.restriction==RS2::RestrictOrthogonal);
162     restrictVertical->setChecked(s.restriction==RS2::RestrictVertical ||  s.restriction==RS2::RestrictOrthogonal);
163     restrictOrthogonal->setChecked(s.restriction==RS2::RestrictOrthogonal);
164     restrictNothing->setChecked(s.restriction==RS2::RestrictNothing);
165 }
166 
getSnaps(void) const167 RS_SnapMode QG_SnapToolBar::getSnaps ( void ) const
168 {
169     RS_SnapMode s;
170 
171     s.snapFree         = snapFree->isChecked();
172     s.snapGrid         = snapGrid->isChecked();
173     s.snapEndpoint     = snapEnd->isChecked();
174     s.snapOnEntity     = snapOnEntity->isChecked();
175     s.snapCenter       = snapCenter->isChecked();
176     s.snapMiddle       = snapMiddle->isChecked();
177     s.snapDistance       = snapDistance->isChecked();
178     s.snapIntersection = snapIntersection->isChecked();
179     // removed Restrict Othogonal button
180     // todo simplify internal restrict rules
181 	int const rH = (restrictHorizontal && restrictHorizontal->isChecked())? 1:0;
182 	int const rV = (restrictVertical && restrictVertical->isChecked())? 2: 0;
183 	switch (rH + rV) {
184 	case 3:
185 		s.restriction = RS2::RestrictOrthogonal;
186 		break;
187 	case 2:
188 		s.restriction = RS2::RestrictVertical;
189 		break;
190 	case 1:
191 		s.restriction = RS2::RestrictHorizontal;
192 		break;
193 	default:
194 		s.restriction = RS2::RestrictNothing;
195 	}
196 
197     return s;
198 }
199 
lockedRelativeZero() const200 bool QG_SnapToolBar::lockedRelativeZero() const
201 {
202     return bLockRelZero->isChecked();
203 }
204 
setLockedRelativeZero(bool on)205 void QG_SnapToolBar::setLockedRelativeZero(bool on)
206 {
207     bLockRelZero->setChecked(on);
208 }
209 
setActionHandler(QG_ActionHandler * ah)210 void QG_SnapToolBar::setActionHandler(QG_ActionHandler* ah){
211     actionHandler=ah;
212 }
213 
214 /* Slots */
215 
slotRestrictNothing(bool checked)216 void QG_SnapToolBar::slotRestrictNothing(bool checked)
217 {
218 	if( restrictVertical) restrictVertical->setChecked(!checked);
219 	if( restrictHorizontal) restrictHorizontal->setChecked(!checked);
220 	if( restrictOrthogonal) restrictOrthogonal->setChecked(!checked);
221     actionTriggered();
222 }
223 
slotRestrictOrthogonal(bool checked)224 void QG_SnapToolBar::slotRestrictOrthogonal(bool checked)
225 {
226 	if( restrictVertical) restrictVertical->setChecked(checked);
227 	if( restrictHorizontal) restrictHorizontal->setChecked(checked);
228 	if( restrictNothing) restrictNothing->setChecked(checked);
229     actionTriggered();
230 }
231 
actionTriggered()232 void QG_SnapToolBar::actionTriggered()
233 {
234     actionHandler->slotSetSnaps(getSnaps());
235 }
236 
237