Subversion Repositories Scribus

Rev

Rev 18007 | Rev 19093 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
11005 fschmid 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.,                                        *
18122 mrdocs 24
*   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.              *
11005 fschmid 25
****************************************************************************/
26
 
13805 jghali 27
#include "pathfinder.h"
28
 
11038 fschmid 29
#include "pageitem_polygon.h"
11005 fschmid 30
#include "pathfinderdialog.h"
13805 jghali 31
#include "selection.h"
11005 fschmid 32
#include "scribuscore.h"
12669 fschmid 33
#include "sccolorengine.h"
13805 jghali 34
#include "ui/propertiespalette.h"
17424 craig 35
#include "undomanager.h"
36
#include "undostate.h"
12669 fschmid 37
#include "util_color.h"
11017 fschmid 38
#include "util_math.h"
11042 fschmid 39
#include "util_icon.h"
11005 fschmid 40
 
13805 jghali 41
#include <QMessageBox>
42
#include <QPixmap>
43
 
11005 fschmid 44
int pathfinder_getPluginAPIVersion()
45
{
46
        return PLUGIN_API_VERSION;
47
}
48
 
49
ScPlugin* pathfinder_getPlugin()
50
{
51
        PathFinderPlugin* plug = new PathFinderPlugin();
52
        Q_CHECK_PTR(plug);
53
        return plug;
54
}
55
 
56
void pathfinder_freePlugin(ScPlugin* plugin)
57
{
58
        PathFinderPlugin* plug = dynamic_cast<PathFinderPlugin*>(plugin);
59
        Q_ASSERT(plug);
60
        delete plug;
61
}
62
 
63
PathFinderPlugin::PathFinderPlugin() : ScActionPlugin()
64
{
65
        // Set action info in languageChange, so we only have to do
66
        // it in one place.
67
        languageChange();
68
}
69
 
17747 craig 70
PathFinderPlugin::~PathFinderPlugin() {}
11005 fschmid 71
 
72
void PathFinderPlugin::languageChange()
73
{
74
        // Note that we leave the unused members unset. They'll be initialised
75
        // with their default ctors during construction.
76
        // Action name
77
        m_actionInfo.name = "PathFinder";
78
        // Action text for menu, including accel
79
        m_actionInfo.text = tr("Path Operations...");
80
        // Menu
11038 fschmid 81
        m_actionInfo.menu = "ItemPathOps";
11050 fschmid 82
        m_actionInfo.parentMenu = "Item";
83
        m_actionInfo.subMenuName = tr("Path Tools");
11042 fschmid 84
//      m_actionInfo.toolbar = "Vector";
85
//      m_actionInfo.toolBarName = tr("Vector-Tools");
86
//      m_actionInfo.icon1 = loadIcon("pathintersection.png");
87
//      m_actionInfo.icon2 = loadIcon("pathintersection.png");
12566 cbradney 88
        m_actionInfo.enabledOnStartup = false;
11005 fschmid 89
        m_actionInfo.notSuitableFor.append(PageItem::Line);
90
        m_actionInfo.notSuitableFor.append(PageItem::TextFrame);
91
        m_actionInfo.notSuitableFor.append(PageItem::ImageFrame);
92
        m_actionInfo.notSuitableFor.append(PageItem::PolyLine);
93
        m_actionInfo.notSuitableFor.append(PageItem::PathText);
94
        m_actionInfo.notSuitableFor.append(PageItem::LatexFrame);
15060 fschmid 95
        m_actionInfo.notSuitableFor.append(PageItem::Symbol);
16191 fschmid 96
        m_actionInfo.notSuitableFor.append(PageItem::RegularPolygon);
16215 fschmid 97
        m_actionInfo.notSuitableFor.append(PageItem::Arc);
16311 fschmid 98
        m_actionInfo.notSuitableFor.append(PageItem::Spiral);
11005 fschmid 99
        m_actionInfo.needsNumObjects = 2;
100
}
101
 
102
const QString PathFinderPlugin::fullTrName() const
103
{
104
        return QObject::tr("PathFinder");
105
}
106
 
107
const ScActionPlugin::AboutData* PathFinderPlugin::getAboutData() const
108
{
109
        AboutData* about = new AboutData;
110
        Q_CHECK_PTR(about);
111
        about->authors = QString::fromUtf8("Franz Schmid <Franz.Schmid@altmuehlnet.de>");
112
        about->shortDescription = tr("Path Operations");
113
        about->description = tr("Apply fancy boolean operations to paths.");
114
        // about->version
115
        // about->releaseDate
116
        // about->copyright
117
        about->license = "GPL";
118
        return about;
119
}
120
 
121
void PathFinderPlugin::deleteAboutData(const AboutData* about) const
122
{
123
        Q_ASSERT(about);
124
        delete about;
125
}
126
 
127
bool PathFinderPlugin::run(ScribusDoc* doc, QString)
128
{
129
        ScribusDoc* currDoc = doc;
130
        if (currDoc == 0)
131
                currDoc = ScCore->primaryMainWindow()->doc;
17424 craig 132
        if (currDoc->m_Selection->count() <= 1)
133
                return true;
134
 
135
        //<<#9046
136
        UndoTransaction* activeTransaction = NULL;
137
        UndoManager* undoManager = UndoManager::instance();
138
        if (UndoManager::undoEnabled())
139
                activeTransaction = new UndoTransaction(undoManager->beginTransaction(Um::SelectionGroup, Um::IDocument, Um::PathOperation, "", Um::IPolygon));
140
        //>>#9046
141
 
142
        PageItem *Item1 = currDoc->m_Selection->itemAt(0);
143
        PageItem *Item2 = currDoc->m_Selection->itemAt(1);
144
        PathFinderDialog *dia = new PathFinderDialog(currDoc->scMW(), currDoc, Item1, Item2);
145
        if (dia->exec())
11005 fschmid 146
        {
17424 craig 147
                int opMode=dia->opMode;
148
                if (dia->keepItem1)
11005 fschmid 149
                {
17424 craig 150
                        PageItem *newItem;
151
                        if (dia->swapped)
11038 fschmid 152
                        {
17424 craig 153
                                newItem = new PageItem_Polygon(*Item2);
154
                                newItem->setSelected(false);
155
                                currDoc->Items->insert(currDoc->Items->indexOf(Item2), newItem);
156
                        }
157
                        else
158
                        {
159
                                newItem = new PageItem_Polygon(*Item1);
160
                                newItem->setSelected(false);
161
                                currDoc->Items->insert(currDoc->Items->indexOf(Item1), newItem);
162
                        }
163
                        if (UndoManager::undoEnabled())
164
                        {
165
                                ScItemState<PageItem*> *is = new ScItemState<PageItem*>("Create PageItem");
166
                                is->set("CREATE_ITEM", "create_item");
167
                                is->setItem(newItem);
168
                                UndoObject *target = currDoc->Pages->at(Item1->OwnPage);
169
                                undoManager->action(target, is);
170
                        }
171
                }
172
                if (dia->keepItem2)
173
                {
174
                        PageItem *newItem;
175
                        if (dia->swapped)
176
                        {
177
                                newItem = new PageItem_Polygon(*Item1);
178
                                newItem->setSelected(false);
179
                                currDoc->Items->insert(currDoc->Items->indexOf(Item1), newItem);
180
                        }
181
                        else
182
                        {
183
                                newItem = new PageItem_Polygon(*Item2);
184
                                newItem->setSelected(false);
185
                                currDoc->Items->insert(currDoc->Items->indexOf(Item2), newItem);
186
                        }
187
                        if (UndoManager::undoEnabled())
188
                        {
189
                                ScItemState<PageItem*> *is = new ScItemState<PageItem*>("Create PageItem");
190
                                is->set("CREATE_ITEM", "create_item");
191
                                is->setItem(newItem);
192
                                UndoObject *target = currDoc->Pages->at(Item1->OwnPage);
193
                                undoManager->action(target, is);
194
                        }
195
                }
196
                if (opMode != 4)
197
                {
198
                        PageItem *currItem;
199
                        QPainterPath path;
200
                        FPointArray points;
201
                        if (dia->targetColor == 0)
202
                        {
203
                                currItem = Item1;
11038 fschmid 204
                                if (dia->swapped)
13287 fschmid 205
                                {
17424 craig 206
                                        currItem = Item2;
207
                                        currItem->setXYPos(Item1->xPos(), Item1->yPos());
208
                                        currItem->setRotation(0.0);
13287 fschmid 209
                                }
17424 craig 210
                        }
211
                        else
212
                        {
213
                                if (dia->swapped)
214
                                        currItem = Item1;
11038 fschmid 215
                                else
13287 fschmid 216
                                {
17424 craig 217
                                        currItem = Item2;
218
                                        currItem->setXYPos(Item1->xPos(), Item1->yPos());
219
                                        currItem->setRotation(0.0);
13287 fschmid 220
                                }
11038 fschmid 221
                        }
17424 craig 222
                        path = dia->result;
223
                        points.fromQPainterPath(path);
224
 
225
                        //<<#9046
226
                        FPointArray oldPOLine=currItem->PoLine;
227
                        FPointArray oldContourLine=currItem->ContourLine;
228
                        ScItemState<QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> > >* state = NULL;
229
                        if (UndoManager::undoEnabled())
11038 fschmid 230
                        {
17424 craig 231
                                state = new ScItemState<QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> > >(Um::PathOperation);
232
                                state->set("PATH_OPERATION", "path_operation");
233
                                state->set("PATH_OP_OLD_CLIPEDITED", currItem->ClipEdited);
234
                                state->set("PATH_OP_OLD_FRAMETYPE", currItem->FrameType);
235
                                state->set("PATH_OP_OLD_OLDB2", currItem->OldB2);
236
                                state->set("PATH_OP_OLD_OLDH2", currItem->OldH2);
237
                                state->set("PATH_OP_NEW_FRAME", false);
238
                                state->set("PATH_OP_NEW_CLIPEDITED", true);
239
                                state->set("PATH_OP_NEW_FRAMETYPE", 3);
240
                        }
241
                        //>>#9046
242
 
243
                        currItem->PoLine = points;
244
                        currItem->ClipEdited = true;
245
                        currItem->FrameType = 3;
246
                        currDoc->AdjustItemSize(currItem);
247
                        currItem->OldB2 = currItem->width();
248
                        currItem->OldH2 = currItem->height();
249
                        currItem->updateClip();
250
                        currItem->ContourLine = currItem->PoLine.copy();
251
 
252
                        //<<#9046
253
                        if (UndoManager::undoEnabled())
254
                        {
255
                                state->set("PATH_OP_NEW_OLDB2", currItem->OldB2);
256
                                state->set("PATH_OP_NEW_OLDH2", currItem->OldH2);
257
                                state->setItem(QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> >(QPair<FPointArray, FPointArray>(oldPOLine, oldContourLine), QPair<FPointArray, FPointArray>(points, currItem->ContourLine)));
258
                                undoManager->action(currItem, state);
259
                        }
260
                        //>>#9046
261
 
262
                        currDoc->m_Selection->removeItem(currItem);
263
                        currDoc->itemSelection_DeleteItem();
264
                }
265
                else
266
                {
267
                        QPainterPath path;
268
                        FPointArray points;
269
                        PageItem *newItem;
270
                        double i1x = Item1->xPos();
271
                        double i1y = Item1->yPos();
272
                        path = dia->result;
273
                        if (!path.isEmpty())
274
                        {
275
                                points.fromQPainterPath(path);
276
                                //<<#9046
277
                                FPointArray oldPOLine=Item1->PoLine;
278
                                FPointArray oldContourLine=Item1->ContourLine;
279
                                ScItemState<QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> > >* state = NULL;
280
                                if (UndoManager::undoEnabled())
13287 fschmid 281
                                {
17424 craig 282
                                        state = new ScItemState<QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> > >(Um::PathOperation);
283
                                        state->set("PATH_OPERATION", "path_operation");
284
                                        state->set("PATH_OP_OLD_CLIPEDITED", Item1->ClipEdited);
285
                                        state->set("PATH_OP_OLD_FRAMETYPE", Item1->FrameType);
286
                                        state->set("PATH_OP_OLD_OLDB2", Item1->OldB2);
287
                                        state->set("PATH_OP_OLD_OLDH2", Item1->OldH2);
288
                                        state->set("PATH_OP_NEW_FRAME", false);
289
                                        state->set("PATH_OP_NEW_CLIPEDITED", true);
290
                                        state->set("PATH_OP_NEW_FRAMETYPE", 3);
13287 fschmid 291
                                }
17424 craig 292
                                //>>#9046
293
                                Item1->PoLine = points;
294
                                Item1->ClipEdited = true;
295
                                Item1->FrameType = 3;
296
                                currDoc->AdjustItemSize(Item1);
297
                                Item1->OldB2 = Item1->width();
298
                                Item1->OldH2 = Item1->height();
299
                                Item1->updateClip();
300
                                Item1->ContourLine = Item1->PoLine.copy();
301
                                //<<#9046
302
                                if (UndoManager::undoEnabled())
13287 fschmid 303
                                {
17424 craig 304
                                        state->set("PATH_OP_NEW_OLDB2", Item1->OldB2);
305
                                        state->set("PATH_OP_NEW_OLDH2", Item1->OldH2);
306
                                        state->setItem(QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> >(QPair<FPointArray, FPointArray>(oldPOLine, oldContourLine), QPair<FPointArray, FPointArray>(Item1->PoLine, Item1->ContourLine)));
307
                                        undoManager->action(Item1, state);
13287 fschmid 308
                                }
17424 craig 309
                                //>>#9046
11038 fschmid 310
                        }
17424 craig 311
 
312
                        path = QPainterPath();
313
                        path = dia->result1;
314
                        if (!path.isEmpty())
11038 fschmid 315
                        {
17424 craig 316
                                points.fromQPainterPath(path);
317
                                //<<#9046
318
                                FPointArray oldPOLine=Item2->PoLine;
319
                                FPointArray oldContourLine=Item2->ContourLine;
320
                                ScItemState<QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> > >* state = NULL;
321
                                if (UndoManager::undoEnabled())
11038 fschmid 322
                                {
17424 craig 323
                                        state = new ScItemState<QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> > >(Um::PathOperation);
324
                                        state->set("PATH_OPERATION", "path_operation");
325
                                        state->set("PATH_OP_OLD_CLIPEDITED", Item2->ClipEdited);
326
                                        state->set("PATH_OP_OLD_FRAMETYPE", Item2->FrameType);
327
                                        state->set("PATH_OP_OLD_OLDB2", Item2->OldB2);
328
                                        state->set("PATH_OP_OLD_OLDH2", Item2->OldH2);
329
                                        state->set("PATH_OP_NEW_FRAME", false);
330
                                        state->set("PATH_OP_NEW_CLIPEDITED", true);
331
                                        state->set("PATH_OP_NEW_FRAMETYPE", 3);
11038 fschmid 332
                                }
17424 craig 333
                                //>>#9046
334
                                Item2->setXYPos(i1x, i1y);
335
                                Item2->setRotation(0.0);
336
                                Item2->PoLine = points;
337
                                Item2->ClipEdited = true;
338
                                Item2->FrameType = 3;
339
                                currDoc->AdjustItemSize(Item2);
340
                                Item2->OldB2 = Item2->width();
341
                                Item2->OldH2 = Item2->height();
342
                                Item2->updateClip();
343
                                Item2->ContourLine = Item2->PoLine.copy();
344
                                //<<#9046
345
                                if (UndoManager::undoEnabled())
11038 fschmid 346
                                {
17424 craig 347
                                        state->set("PATH_OP_NEW_OLDB2", Item2->OldB2);
348
                                        state->set("PATH_OP_NEW_OLDH2", Item2->OldH2);
349
                                        state->setItem(QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> >(QPair<FPointArray, FPointArray>(oldPOLine, oldContourLine), QPair<FPointArray, FPointArray>(Item2->PoLine, Item2->ContourLine)));
350
                                        undoManager->action(Item2, state);
11038 fschmid 351
                                }
17424 craig 352
                                //>>#9046
11038 fschmid 353
                        }
17424 craig 354
 
355
                        path = QPainterPath();
356
                        path = dia->result2;
357
                        if (!path.isEmpty())
11038 fschmid 358
                        {
17424 craig 359
                                if (dia->targetColor == 0)
11039 fschmid 360
                                {
17424 craig 361
                                        newItem = new PageItem_Polygon(*Item1);
362
                                        newItem->setXYPos(i1x, i1y);
11039 fschmid 363
                                }
17424 craig 364
                                else
11038 fschmid 365
                                {
17424 craig 366
                                        newItem = new PageItem_Polygon(*Item2);
367
                                        newItem->setXYPos(i1x, i1y);
368
                                        newItem->setRotation(0.0);
11038 fschmid 369
                                }
17424 craig 370
                                currDoc->Items->append(newItem);
371
                                newItem->setSelected(false);
372
                                points.fromQPainterPath(path);
373
                                newItem->PoLine = points;
374
                                newItem->ClipEdited = true;
375
                                newItem->FrameType = 3;
376
                                currDoc->AdjustItemSize(newItem);
377
                                newItem->OldB2 = newItem->width();
378
                                newItem->OldH2 = newItem->height();
379
                                newItem->updateClip();
380
                                newItem->ContourLine = newItem->PoLine.copy();
381
                                if (dia->targetColor == 2)
11039 fschmid 382
                                {
17424 craig 383
                                        QString fill = dia->getOtherFillColor();
384
                                        if (fill == CommonStrings::tr_NoneColor)
385
                                                fill = CommonStrings::None;
386
                                        newItem->setFillColor(fill);
387
                                        QString stroke = dia->getOtherLineColor();
388
                                        if (stroke == CommonStrings::tr_NoneColor)
389
                                                stroke = CommonStrings::None;
390
                                        newItem->setLineColor(stroke);
11039 fschmid 391
                                }
11038 fschmid 392
                        }
17424 craig 393
                        currDoc->m_Selection->clear();
394
                        currDoc->view()->Deselect(true);
11005 fschmid 395
                }
17424 craig 396
                currDoc->changed();
397
                currDoc->view()->DrawNew();
11005 fschmid 398
        }
17424 craig 399
        delete dia;
400
 
401
        //<<#9046
402
        if (activeTransaction)
403
        {
404
                activeTransaction->commit();
405
                delete activeTransaction;
406
                activeTransaction = NULL;
407
        }
408
        //>>#9046
409
 
11005 fschmid 410
        return true;
411
}