1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 /***************************************************************************
8 * Copyright (C) 2007 by Franz Schmid *
9 * franz.schmid@altmuehlnet.de *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
25 ****************************************************************************/
26
27 #include "subdivide.h"
28 #include "scribuscore.h"
29 #include "scribusdoc.h"
30 #include "appmodes.h"
31 #include "selection.h"
32
subdivide_getPluginAPIVersion()33 int subdivide_getPluginAPIVersion()
34 {
35 return PLUGIN_API_VERSION;
36 }
37
subdivide_getPlugin()38 ScPlugin* subdivide_getPlugin()
39 {
40 SubdividePlugin* plug = new SubdividePlugin();
41 Q_CHECK_PTR(plug);
42 return plug;
43 }
44
subdivide_freePlugin(ScPlugin * plugin)45 void subdivide_freePlugin(ScPlugin* plugin)
46 {
47 SubdividePlugin* plug = qobject_cast<SubdividePlugin*>(plugin);
48 Q_ASSERT(plug);
49 delete plug;
50 }
51
SubdividePlugin()52 SubdividePlugin::SubdividePlugin()
53 {
54 // Set action info in languageChange, so we only have to do
55 // it in one place.
56 languageChange();
57 }
58
~SubdividePlugin()59 SubdividePlugin::~SubdividePlugin() {};
60
languageChange()61 void SubdividePlugin::languageChange()
62 {
63 // Note that we leave the unused members unset. They'll be initialised
64 // with their default ctors during construction.
65 // Action name
66 m_actionInfo.name = "Subdivide";
67 // Action text for menu, including accel
68 m_actionInfo.text = tr("Subdivide Path");
69 m_actionInfo.helpText = tr("Subdivide a path by inserting new Nodes.");
70 // Menu
71 m_actionInfo.menu = "ItemPathOps";
72 m_actionInfo.parentMenu = "Item";
73 m_actionInfo.subMenuName = tr("Path Tools");
74 m_actionInfo.enabledOnStartup = false;
75 m_actionInfo.notSuitableFor.append(PageItem::Line);
76 m_actionInfo.notSuitableFor.append(PageItem::Symbol);
77 m_actionInfo.forAppMode.append(modeEditClip);
78 m_actionInfo.needsNumObjects = 1;
79 }
80
fullTrName() const81 QString SubdividePlugin::fullTrName() const
82 {
83 return QObject::tr("Subdivide");
84 }
85
getAboutData() const86 const ScActionPlugin::AboutData* SubdividePlugin::getAboutData() const
87 {
88 AboutData* about = new AboutData;
89 Q_CHECK_PTR(about);
90 about->authors = QString::fromUtf8("Franz Schmid <Franz.Schmid@altmuehlnet.de>");
91 about->shortDescription = tr("Subdivide");
92 about->description = tr("Subdivide selected Path");
93 // about->version
94 // about->releaseDate
95 // about->copyright
96 about->license = "GPL";
97 return about;
98 }
99
deleteAboutData(const AboutData * about) const100 void SubdividePlugin::deleteAboutData(const AboutData* about) const
101 {
102 Q_ASSERT(about);
103 delete about;
104 }
105
run(ScribusDoc * doc,const QString &)106 bool SubdividePlugin::run(ScribusDoc* doc, const QString&)
107 {
108 ScribusDoc* currDoc = doc;
109 if (currDoc == nullptr)
110 currDoc = ScCore->primaryMainWindow()->doc;
111 double nearT = 0.5;
112 uint docSelectionCount = currDoc->m_Selection->count();
113 if (docSelectionCount != 0)
114 {
115 for (uint aa = 0; aa < docSelectionCount; ++aa)
116 {
117 FPointArray points;
118 PageItem *currItem = currDoc->m_Selection->itemAt(aa);
119 if (currDoc->nodeEdit.isContourLine())
120 {
121 uint psize = currItem->ContourLine.size();
122 for (uint a = 0; a < psize-3; a += 4)
123 {
124 if (currItem->ContourLine.isMarker(a))
125 {
126 points.setMarker();
127 continue;
128 }
129 FPoint base = currItem->ContourLine.point(a);
130 FPoint c1 = currItem->ContourLine.point(a+1);
131 FPoint base2 = currItem->ContourLine.point(a+2);
132 FPoint c2 = currItem->ContourLine.point(a+3);
133 FPoint cn1 = (1.0 - nearT) * base + nearT * c1;
134 FPoint cn2 = (1.0 - nearT) * cn1 + nearT * ((1.0 - nearT) * c1 + nearT * c2);
135 FPoint cn3 = (1.0 - nearT) * ((1.0 - nearT) * c1 + nearT * c2) + nearT * ((1.0 - nearT) * c2 + nearT * base2);
136 FPoint cn4 = (1.0 - nearT) * c2 + nearT * base2;
137 FPoint bp1 = (1.0 - nearT) * cn2 + nearT * cn3;
138 if ((base == c1) && (base2 == c2))
139 {
140 points.addPoint(base);
141 points.addPoint(c1);
142 points.addPoint(bp1);
143 points.addPoint(bp1);
144 points.addPoint(bp1);
145 points.addPoint(bp1);
146 points.addPoint(base2);
147 points.addPoint(c2);
148 }
149 else
150 {
151 points.addPoint(base);
152 points.addPoint(cn1);
153 points.addPoint(bp1);
154 points.addPoint(cn2);
155 points.addPoint(bp1);
156 points.addPoint(cn3);
157 points.addPoint(base2);
158 points.addPoint(cn4);
159 }
160 }
161 currItem->ContourLine = points;
162 }
163 else
164 {
165 uint psize = currItem->PoLine.size();
166 for (uint a = 0; a < psize-3; a += 4)
167 {
168 if (currItem->PoLine.isMarker(a))
169 {
170 points.setMarker();
171 continue;
172 }
173 FPoint base = currItem->PoLine.point(a);
174 FPoint c1 = currItem->PoLine.point(a+1);
175 FPoint base2 = currItem->PoLine.point(a+2);
176 FPoint c2 = currItem->PoLine.point(a+3);
177 FPoint cn1 = (1.0 - nearT) * base + nearT * c1;
178 FPoint cn2 = (1.0 - nearT) * cn1 + nearT * ((1.0 - nearT) * c1 + nearT * c2);
179 FPoint cn3 = (1.0 - nearT) * ((1.0 - nearT) * c1 + nearT * c2) + nearT * ((1.0 - nearT) * c2 + nearT * base2);
180 FPoint cn4 = (1.0 - nearT) * c2 + nearT * base2;
181 FPoint bp1 = (1.0 - nearT) * cn2 + nearT * cn3;
182 if ((base == c1) && (base2 == c2))
183 {
184 points.addPoint(base);
185 points.addPoint(c1);
186 points.addPoint(bp1);
187 points.addPoint(bp1);
188 points.addPoint(bp1);
189 points.addPoint(bp1);
190 points.addPoint(base2);
191 points.addPoint(c2);
192 }
193 else
194 {
195 points.addPoint(base);
196 points.addPoint(cn1);
197 points.addPoint(bp1);
198 points.addPoint(cn2);
199 points.addPoint(bp1);
200 points.addPoint(cn3);
201 points.addPoint(base2);
202 points.addPoint(cn4);
203 }
204 }
205 currItem->PoLine = points;
206 currItem->ClipEdited = true;
207 currItem->FrameType = 3;
208 currDoc->adjustItemSize(currItem);
209 currItem->OldB2 = currItem->width();
210 currItem->OldH2 = currItem->height();
211 currItem->updateClip();
212 }
213 }
214 currDoc->regionsChanged()->update(QRectF());
215 currDoc->changed();
216 }
217 return true;
218 }
219