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 <QMouseEvent>
27 #include "qg_cadtoolbar.h"
28 #include "rs_dialogfactory.h"
29 #include "rs_actioninterface.h"
30 #include "qg_cadtoolbararcs.h"
31 #include "qg_cadtoolbarcircles.h"
32 #include "qg_cadtoolbardim.h"
33 #include "qg_cadtoolbarellipses.h"
34 #include "qg_cadtoolbarinfo.h"
35 #include "qg_cadtoolbarlines.h"
36 #include "qg_cadtoolbarmain.h"
37 #include "qg_cadtoolbarmodify.h"
38 #include "qg_cadtoolbarpolylines.h"
39 #include "qg_cadtoolbarselect.h"
40 #include "qg_cadtoolbarsplines.h"
41 #include "rs_debug.h"
42 
43 #include "qc_applicationwindow.h"
44 
45 /*
46  *  Constructs a QG_CadToolBar as a child of 'parent', with the
47  *  name 'name' and widget flags set to 'f'.
48  */
QG_CadToolBar(QWidget * parent,const char * name)49 QG_CadToolBar::QG_CadToolBar(QWidget* parent, const char* name)
50     : QToolBar(parent)
51 	,actionHandler(nullptr)
52 {
53     setObjectName(name);
54 	setCursor(Qt::ArrowCursor);
55 #if QT_VERSION >= 0x050500
56     auto const dPxlRatio=QC_ApplicationWindow::getAppWindow()->devicePixelRatio();
57     setMinimumSize(73*dPxlRatio,400*dPxlRatio);
58 #else
59     setMinimumSize(73,400);
60 #endif
61     setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
62     setFloatable(false);
63 	init();
64 }
65 
66 /*
67  *  Sets the strings of the subwidgets using the current
68  *  language.
69  */
70 //void QG_CadToolBar::languageChange()
71 //{
72 //    retranslateUi(this);
73 //}
74 
init()75 void QG_CadToolBar::init() {
76 	//create sub cad toolbars
77 	const std::initializer_list<LC_CadToolBarInterface*> tbs={
78 		new QG_CadToolBarMain(this)
79 		,new QG_CadToolBarLines(this)
80 		,new QG_CadToolBarArcs(this)
81 		,new QG_CadToolBarCircles(this)
82 		,new QG_CadToolBarEllipses(this)
83 		,new QG_CadToolBarSplines(this)
84 		,new QG_CadToolBarPolylines(this)
85 		,new QG_CadToolBarDim(this)
86 		,new QG_CadToolBarInfo(this)
87 		,new QG_CadToolBarModify(this)
88 		,new QG_CadToolBarSelect(this)
89 	};
90 
91 	for(auto p: tbs){
92 		p->hide();
93 		m_toolbars[p->rtti()]= p;
94 	}
95 }
96 
sizeHint() const97 QSize 	QG_CadToolBar::sizeHint() const
98 {
99     return QSize(-1, -1);
100 }
101 
populateSubToolBar(const std::vector<QAction * > & actions,RS2::ToolBarId toolbarID)102 void QG_CadToolBar::populateSubToolBar(const std::vector<QAction*>& actions, RS2::ToolBarId toolbarID)
103 {
104 	RS_DEBUG->print("QG_CadToolBar::populateSubToolBar(): begin\n");
105 
106 	if(!m_toolbars.count(toolbarID)) return;
107 	LC_CadToolBarInterface*const p = m_toolbars[toolbarID];
108 	p->addSubActions(actions, true);
109 
110 	RS_DEBUG->print("QG_CadToolBar::populateSubToolBar(): end\n");
111 }
112 
113 /**
114  * Called from the sub toolbar
115  */
back()116 void QG_CadToolBar::back() {
117 	finishCurrentAction(false);
118     showPreviousToolBar(true);
119     //    emit(signalBack());
120 }
121 
finishCurrentAction(bool resetToolBar)122 void QG_CadToolBar::finishCurrentAction(bool resetToolBar)
123 {
124 	if(!actionHandler) return;
125 	RS_ActionInterface* currentAction =actionHandler->getCurrentAction();
126 	if(currentAction) {
127 		currentAction->finish(resetToolBar); //finish the action, but do not update toolBar
128 	}
129 }
130 /**
131  * Called from the application.
132  */
forceNext()133 void QG_CadToolBar::forceNext() {
134     if(activeToolbars.size()==0) return;
135 	auto p=activeToolbars.back();
136 	if (p && p->rtti() == RS2::ToolBarSelect)
137 		p->runNextAction();
138 }
139 
mouseReleaseEvent(QMouseEvent * e)140 void QG_CadToolBar::mouseReleaseEvent(QMouseEvent* e) {
141     if (e->button()==Qt::RightButton) {
142         back();
143         e->accept();
144     }
145 }
146 
contextMenuEvent(QContextMenuEvent * e)147 void QG_CadToolBar::contextMenuEvent(QContextMenuEvent *e) {
148     e->accept();
149 }
150 
151 /**
152  * Creates all tool bars and shows the main toolbar.
153  *
154  * @param ah Pointer to action handler which will deal with the actions in this tool bar.
155  */
setActionHandler(QG_ActionHandler * ah)156 void QG_CadToolBar::setActionHandler(QG_ActionHandler* ah) {
157 	actionHandler = ah;
158 	for(const auto& p: m_toolbars){
159 		p.second->setActionHandler(ah);
160 	}
161 }
162 
hideSubToolBars()163 void QG_CadToolBar::hideSubToolBars(){
164 	for(auto p: activeToolbars){
165 		p->hide();
166 	}
167 }
168 
showSubToolBar()169 void QG_CadToolBar::showSubToolBar(){
170 	LC_CadToolBarInterface* const p = activeToolbars.back();
171 	if (!p->isVisible()) { // On OSX, without this line LibreCAD wuld crash. Not sure if it's a Qt problem or 'somewhere' logic within LibreCAD
172         //shift down to show the handle to move the toolbar
173         //has to be 20, 10 is not enough
174 		p->move(0,20);
175 		p->show();
176     }
177     p->resize(size());
178     adjustSize();
179 }
180 
showPreviousToolBar(bool cleanup)181 void QG_CadToolBar::showPreviousToolBar(bool cleanup) {
182 	// cleanup mouse hint when showing previous tool bar, bug#3480121
183 	RS_DIALOGFACTORY->updateMouseWidget();
184 //	for(auto p: activeToolbars){
185 //		qDebug()<<"QG_CadToolBar::showPreviousToolBar():begin "<<p->rtti();
186 //	}
187 	if(cleanup){
188 		if(actionHandler) {
189 			RS_ActionInterface* currentAction =actionHandler->getCurrentAction();
190 			if(currentAction && currentAction->rtti() != RS2::ActionDefault) {
191 				currentAction->finish(false); //finish the action, but do not update toolBar
192 			}
193 		}
194 		if(activeToolbars.size()>1){
195 			if(activeToolbars.back()) activeToolbars.back() ->setVisible(false);
196 			activeToolbars.pop_back();
197 		}
198 		//        std::cout<<"QG_CadToolBar::showPreviousToolBar(true): toolbars.size()="<<toolbars.size()<<std::endl;
199 		showToolBar(activeToolbars.back()->rtti());
200 	}else{
201 		hideSubToolBars();
202 		//        std::cout<<"QG_CadToolBar::showPreviousToolBar(false): toolbars.size()="<<toolbars.size()<<std::endl;
203 		if(activeToolbars.size()>1){
204 			//            std::cout<<"QG_CadToolBar::showPreviousToolBar(false): hide:"<<toolbarIDs[toolbars.size()-1]<<std::endl;
205 			if (!activeToolbars.back()) activeToolbars.back()->setVisible(false);
206 			activeToolbars.pop_back();
207 		}
208 
209 		//        std::cout<<"QG_CadToolBar::showPreviousToolBar(false): toolbars.size()="<<toolbars.size()<<std::endl;
210 		showSubToolBar();
211 	}
212 //	for(auto p: activeToolbars){
213 //		qDebug()<<"QG_CadToolBar::showPreviousToolBar():end "<<p->rtti();
214 //	}
215 }
216 
showToolBar(RS2::ToolBarId id,bool restoreAction)217 void QG_CadToolBar::showToolBar(RS2::ToolBarId id, bool restoreAction ) {
218 
219 	LC_CadToolBarInterface* newTb;
220 	if(m_toolbars.count(id)){
221 		newTb=m_toolbars[id];
222 	}else{
223 		newTb=m_toolbars[RS2::ToolBarMain];
224 	}
225 	if(restoreAction) newTb->restoreAction();
226 	hideSubToolBars();
227 	auto it=std::find(activeToolbars.begin(), activeToolbars.end(), newTb);
228 	if(it != activeToolbars.end()){
229 		activeToolbars.erase(it+1,activeToolbars.end());
230 	}
231 	if(!( activeToolbars.size()>0 && newTb == activeToolbars.back())) {
232 		activeToolbars.push_back(newTb);
233 	}
234 	showSubToolBar();
235 	adjustSize();
236 }
237 
resetToolBar()238 void QG_CadToolBar::resetToolBar() {
239 	LC_CadToolBarInterface* currentTb=activeToolbars.back();
240 	currentTb->resetToolBar();
241 }
242 
showToolBarMain()243 void QG_CadToolBar::showToolBarMain() {
244     showToolBar(RS2::ToolBarMain);
245 }
246 
showToolBarLines()247 void QG_CadToolBar::showToolBarLines() {
248     showToolBar(RS2::ToolBarLines);
249 }
250 
showToolBarArcs()251 void QG_CadToolBar::showToolBarArcs() {
252     showToolBar(RS2::ToolBarArcs);
253 }
254 
showToolBarEllipses()255 void QG_CadToolBar::showToolBarEllipses() {
256     showToolBar(RS2::ToolBarEllipses);
257 }
258 
showToolBarSplines()259 void QG_CadToolBar::showToolBarSplines() {
260     showToolBar(RS2::ToolBarSplines);
261 }
262 
showToolBarPolylines()263 void QG_CadToolBar::showToolBarPolylines() {
264     showToolBar(RS2::ToolBarPolylines);
265 }
266 
showToolBarCircles()267 void QG_CadToolBar::showToolBarCircles() {
268     showToolBar(RS2::ToolBarCircles);
269 }
270 
showToolBarInfo()271 void QG_CadToolBar::showToolBarInfo() {
272     showToolBar(RS2::ToolBarInfo);
273 }
274 
showToolBarModify()275 void QG_CadToolBar::showToolBarModify() {
276     showToolBar(RS2::ToolBarModify);
277 }
278 
showToolBarDim()279 void QG_CadToolBar::showToolBarDim() {
280     showToolBar(RS2::ToolBarDim);
281 }
282 
showToolBarSelect()283 void QG_CadToolBar::showToolBarSelect() {
284 	showToolBarSelect(nullptr, -1);
285 }
286 
showToolBarSelect(RS_ActionInterface * selectAction,int nextAction)287 void QG_CadToolBar::showToolBarSelect(RS_ActionInterface* selectAction,
288                                       int nextAction) {
289 	auto p=m_toolbars[RS2::ToolBarSelect];
290 
291 	p->setNextAction(nextAction);
292 	p->setSelectAction(selectAction);
293     showToolBar(RS2::ToolBarSelect);
294 	showSubToolBar();
295 }
296 
showCadToolBar(RS2::ActionType actionType,bool cleanup)297 void QG_CadToolBar::showCadToolBar(RS2::ActionType actionType, bool cleanup){
298 	RS2::ToolBarId id=RS2::ToolBarNone;
299     switch(actionType){
300     //no op
301     default:
302         return;
303         //default action resets toolbar, issue#295
304 	case RS2::ActionDefault:
305 		break;
306 	case RS2::ActionDrawImage:
307     case RS2::ActionDrawPoint:
308     case RS2::ActionDrawMText:
309 		id=RS2::ToolBarMain;
310 		break;
311     case RS2::ActionDrawArc:
312     case RS2::ActionDrawArc3P:
313     case RS2::ActionDrawArcParallel:
314     case RS2::ActionDrawArcTangential:
315 		id=RS2::ToolBarArcs;
316         break;
317     case RS2::ActionDrawCircle:
318     case RS2::ActionDrawCircle2P:
319     case RS2::ActionDrawCircle3P:
320     case RS2::ActionDrawCircleCR:
321     case RS2::ActionDrawCircleParallel:
322     case RS2::ActionDrawCircleInscribe:
323     case RS2::ActionDrawCircleTan2:
324     case RS2::ActionDrawCircleTan2_1P:
325     case RS2::ActionDrawCircleTan1_2P:
326 		id=RS2::ToolBarCircles;
327         break;
328     case RS2::ActionDrawEllipseArcAxis:
329     case RS2::ActionDrawEllipseAxis:
330     case RS2::ActionDrawEllipseFociPoint:
331     case RS2::ActionDrawEllipse4Points:
332     case RS2::ActionDrawEllipseCenter3Points:
333     case RS2::ActionDrawEllipseInscribe:
334 		id=RS2::ToolBarEllipses;
335         break;
336     case RS2::ActionDrawSpline:
337     case RS2::ActionDrawSplinePoints:
338 		id=RS2::ToolBarSplines;
339         break;
340     case RS2::ActionDrawLine:
341     case RS2::ActionDrawLineAngle:
342     case RS2::ActionDrawLineBisector:
343     case RS2::ActionDrawLineFree:
344     case RS2::ActionDrawLineHorVert:
345     case RS2::ActionDrawLineHorizontal:
346     case RS2::ActionDrawLineOrthogonal:
347     case RS2::ActionDrawLineOrthTan:
348     case RS2::ActionDrawLineParallel:
349     case RS2::ActionDrawLineParallelThrough:
350     case RS2::ActionDrawLinePolygonCenCor:
351     case RS2::ActionDrawLinePolygonCorCor:
352     case RS2::ActionDrawLineRectangle:
353     case RS2::ActionDrawLineRelAngle:
354     case RS2::ActionDrawLineTangent1:
355     case RS2::ActionDrawLineTangent2:
356     case RS2::ActionDrawLineVertical:
357 		id=RS2::ToolBarLines;
358         break;
359     case RS2::ActionDrawPolyline:
360     case RS2::ActionPolylineAdd:
361     case RS2::ActionPolylineAppend:
362     case RS2::ActionPolylineDel:
363     case RS2::ActionPolylineDelBetween:
364     case RS2::ActionPolylineTrim:
365     case RS2::ActionPolylineEquidistant:
366     case RS2::ActionPolylineSegment:
367 		id=RS2::ToolBarPolylines;
368         break;
369     case RS2::ActionDimAligned:
370     case RS2::ActionDimLinear:
371     case RS2::ActionDimLinearVer:
372     case RS2::ActionDimLinearHor:
373     case RS2::ActionDimRadial:
374     case RS2::ActionDimDiametric:
375     case RS2::ActionDimAngular:
376     case RS2::ActionDimLeader:
377 		id=RS2::ToolBarDim;
378         break;
379     case RS2::ActionModifyAttributes:
380     case RS2::ActionModifyAttributesNoSelect:
381     case RS2::ActionModifyDelete:
382     case RS2::ActionModifyDeleteNoSelect:
383     case RS2::ActionModifyDeleteQuick:
384     case RS2::ActionModifyDeleteFree:
385     case RS2::ActionModifyMove:
386     case RS2::ActionModifyMoveNoSelect:
387     case RS2::ActionModifyRotate:
388     case RS2::ActionModifyRotateNoSelect:
389     case RS2::ActionModifyScale:
390     case RS2::ActionModifyScaleNoSelect:
391     case RS2::ActionModifyMirror:
392     case RS2::ActionModifyMirrorNoSelect:
393     case RS2::ActionModifyMoveRotate:
394     case RS2::ActionModifyMoveRotateNoSelect:
395     case RS2::ActionModifyRotate2:
396     case RS2::ActionModifyRotate2NoSelect:
397     case RS2::ActionModifyEntity:
398     case RS2::ActionModifyTrim:
399     case RS2::ActionModifyTrim2:
400     case RS2::ActionModifyTrimAmount:
401     case RS2::ActionModifyCut:
402     case RS2::ActionModifyStretch:
403     case RS2::ActionModifyBevel:
404     case RS2::ActionModifyRound:
405     case RS2::ActionModifyOffset:
406     case RS2::ActionModifyOffsetNoSelect:
407     case RS2::ActionModifyRevertDirection:
408     case RS2::ActionModifyRevertDirectionNoSelect:
409 		id=RS2::ToolBarModify;
410         break;
411     case RS2::ActionInfoInside:
412     case RS2::ActionInfoDist:
413     case RS2::ActionInfoDist2:
414     case RS2::ActionInfoAngle:
415     case RS2::ActionInfoTotalLength:
416     case RS2::ActionInfoTotalLengthNoSelect:
417     case RS2::ActionInfoArea:
418 		id=RS2::ToolBarInfo;
419         break;
420     }
421 	if(id != RS2::ToolBarNone){
422 		m_toolbars[id]->showCadToolBar(actionType);
423 		showToolBar(id, false);
424 	}
425     if(cleanup){
426 		if(actionHandler ) {
427             RS_ActionInterface* currentAction =actionHandler->getCurrentAction();
428 			if(currentAction ) {
429                 currentAction->finish(false); //finish the action, but do not update toolBar
430             }
431         }
432     }
433 }
434 
435