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 begin : June 2005
9 copyright : (C) 2005 by Craig Bradney
10 email : cbradney@zip.com.au
11 ***************************************************************************/
12
13 /***************************************************************************
14 * *
15 * Scribus program is free software; you can redistribute it and/or modify *
16 * it under the terms of the GNU General Public License as published by *
17 * the Free Software Foundation; either version 2 of the License, or *
18 * (at your option) any later version. *
19 * *
20 ***************************************************************************/
21
22 #include "aligndistribute.h"
23
24 #include <QComboBox>
25 #include <QEvent>
26 #include <QImage>
27 #include <QLabel>
28 #include <QLayout>
29 #include <QLineEdit>
30 #include <QLocale>
31 #include <QMessageBox>
32 #include <QPixmap>
33 #include <QPushButton>
34 #include <QTabWidget>
35 #include <QToolButton>
36 #include <QToolTip>
37 #include <QVariant>
38
39 #include "commonstrings.h"
40 #include "iconmanager.h"
41 #include "localemgr.h"
42 #include "scpage.h"
43 #include "scribusapp.h"
44 #include "scribusdoc.h"
45 #include "scribusstructs.h"
46 #include "selection.h"
47 #include "ui/scrspinbox.h"
48 #include "undomanager.h"
49 #include "units.h"
50
51 //TODO Distribute with
52
AlignDistributePalette(QWidget * parent,const char * name)53 AlignDistributePalette::AlignDistributePalette( QWidget* parent, const char* name) : ScDockPalette(parent, name, Qt::WindowFlags())
54 {
55 setupUi(this);
56 setSizePolicy( QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
57 setObjectName(name);
58
59 //set up scrspinboxes
60 distributeDistSpinBox->setValues(-10000.0, 10000.0, 2, 0.0);
61
62 resize( QSize(100, 100).expandedTo(minimumSizeHint()) );
63 languageChange();
64 init();
65 setDoc(nullptr);
66
67 connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
68 connect(ScQApp, SIGNAL(localeChanged()), this, SLOT(localeChange()));
69 }
70
~AlignDistributePalette()71 AlignDistributePalette::~AlignDistributePalette()
72 {
73 }
74
changeEvent(QEvent * e)75 void AlignDistributePalette::changeEvent(QEvent *e)
76 {
77 if (e->type() == QEvent::LanguageChange)
78 {
79 languageChange();
80 return;
81 }
82 ScDockPalette::changeEvent(e);
83 }
84
languageChange()85 void AlignDistributePalette::languageChange()
86 {
87 retranslateUi(this);
88
89 int alignComboValue=alignRelativeToCombo->currentIndex();
90 alignRelativeToCombo->clear();
91 alignRelativeToCombo->addItem( tr( "First Selected" ) );
92 alignRelativeToCombo->addItem( tr( "Last Selected" ) );
93 alignRelativeToCombo->addItem( tr( "Page" ) );
94 alignRelativeToCombo->addItem( tr( "Margins" ) );
95 alignRelativeToCombo->addItem( tr( "Guide" ) );
96 alignRelativeToCombo->addItem( tr( "Selection" ) );
97 alignRelativeToCombo->setCurrentIndex(alignComboValue);
98 alignRelativeToCombo->setToolTip( tr( "<qt>Align relative to the:<ul><li>First selected item</li><li>Second Selected Item</li><li>The current page</li><li>The margins of the current page</li><li>A Guide</li><li>The selection</ul></qt>" ) );
99 alignToChanged(alignComboValue);
100
101 int alignMethodValue=alignMoveOrResizeCombo->currentIndex();
102 alignMoveOrResizeCombo->clear();
103 alignMoveOrResizeCombo->addItem( tr("Move") );
104 alignMoveOrResizeCombo->addItem( tr("Resize") );
105 alignMoveOrResizeCombo->setToolTip( tr( "<qt>When aligning one side of an item do one of the following:<ul><li>Always move the other side too (preserve existing width and height)</li><li>Keep the other side fixed (resize the item instead of moving it) whenever possible</li></ul></qt>" ));
106 alignMethodChanged(alignMethodValue);
107
108 alignGuideLineEdit->setToolTip( tr( "The location of the selected guide to align to" ) );
109 alignLeftOutToolButton->setToolTip( tr( "Align right sides of items to left side of anchor" ) );
110 alignRightOutToolButton->setToolTip( tr( "Align left sides of items to right side of anchor" ) );
111 alignBottomInToolButton->setToolTip( tr( "Align bottoms" ) );
112 alignRightInToolButton->setToolTip( tr( "Align right sides" ) );
113 alignBottomOutToolButton->setToolTip( tr( "Align tops of items to bottom of anchor" ) );
114 alignCenterHorToolButton->setToolTip( tr( "Center on vertical axis" ) );
115 alignLeftInToolButton->setToolTip( tr( "Align left sides" ) );
116 alignCenterVerToolButton->setToolTip( tr( "Center on horizontal axis" ) );
117 alignTopOutToolButton->setToolTip( tr( "Align bottoms of items to top of anchor" ) );
118 alignTopInToolButton->setToolTip( tr( "Align tops" ) );
119
120 distributeDistHToolButton->setToolTip( tr( "Make horizontal gaps between items equal" ) );
121 distributeDistValueHToolButton->setToolTip( tr( "Make horizontal gaps between items equal to the value specified" ) );
122
123 distributeRightToolButton->setToolTip( tr( "Distribute right sides equidistantly" ) );
124 distributeBottomToolButton->setToolTip( tr( "Distribute bottoms equidistantly" ) );
125 distributeCenterHToolButton->setToolTip( tr( "Distribute centers equidistantly horizontally" ) );
126 distributeDistVToolButton->setToolTip( tr( "Make vertical gaps between items equal" ) );
127 distributeDistValueVToolButton->setToolTip( tr( "Make vertical gaps between items equal to the value specified" ) );
128 distributeLeftToolButton->setToolTip( tr( "Distribute left sides equidistantly" ) );
129 distributeCenterVToolButton->setToolTip( tr( "Distribute centers equidistantly vertically" ) );
130 distributeTopToolButton->setToolTip( tr( "Distribute tops equidistantly" ) );
131 distributeAcrossPageToolButton->setToolTip( tr( "Make horizontal gaps between items and sides of page equal" ) );
132 distributeDownPageToolButton->setToolTip( tr( "Make vertical gaps between items and the top and bottom of page equal" ) );
133 distributeAcrossMarginsToolButton->setToolTip( tr( "Make horizontal gaps between items and sides of page margins equal" ) );
134 distributeDownMarginsToolButton->setToolTip( tr( "Make vertical gaps between items and the top and bottom of page margins equal" ) );
135
136 distributeDistSpinBox->setToolTip( tr( "Distribute the items with the distance specified" ) );
137 reverseDistributionCheckBox->setToolTip( tr("When distributing by a set distance, reverse the direction of the distribution of items") );
138
139 guideInfoTextNone = tr("None Selected");
140
141 swapLeftToolButton->setToolTip( tr( "Swap items to the left" ) );
142 swapRightToolButton->setToolTip( tr( "Swap items to the right" ) );
143 }
144
init()145 void AlignDistributePalette::init()
146 {
147 undoManager = UndoManager::instance();
148
149 iconSetChange();
150
151 connect(alignLeftOutToolButton, SIGNAL(clicked()), this, SLOT(alignLeftOut()));
152 connect(alignRightOutToolButton, SIGNAL(clicked()), this, SLOT(alignRightOut()));
153 connect(alignBottomInToolButton, SIGNAL(clicked()), this, SLOT(alignBottomIn()));
154 connect(alignRightInToolButton, SIGNAL(clicked()), this, SLOT(alignRightIn()));
155 connect(alignBottomOutToolButton, SIGNAL(clicked()), this, SLOT(alignBottomOut()));
156 connect(alignCenterHorToolButton, SIGNAL(clicked()), this, SLOT(alignCenterHor()));
157 connect(alignLeftInToolButton, SIGNAL(clicked()), this, SLOT(alignLeftIn()));
158 connect(alignCenterVerToolButton, SIGNAL(clicked()), this, SLOT(alignCenterVer()));
159 connect(alignTopOutToolButton, SIGNAL(clicked()), this, SLOT(alignTopOut()));
160 connect(alignTopInToolButton, SIGNAL(clicked()), this, SLOT(alignTopIn()));
161 connect(distributeDistHToolButton, SIGNAL(clicked()), this, SLOT(distributeDistH()));
162 connect(distributeDistValueHToolButton, SIGNAL(clicked()), this, SLOT(distributeDistValH()));
163 connect(distributeRightToolButton, SIGNAL(clicked()), this, SLOT(distributeRight()));
164 connect(distributeBottomToolButton, SIGNAL(clicked()), this, SLOT(distributeBottom()));
165 connect(distributeCenterHToolButton, SIGNAL(clicked()), this, SLOT(distributeCenterH()));
166 connect(distributeDistVToolButton, SIGNAL(clicked()), this, SLOT(distributeDistV()));
167 connect(distributeDistValueVToolButton, SIGNAL(clicked()), this, SLOT(distributeDistValV()));
168 connect(distributeLeftToolButton, SIGNAL(clicked()), this, SLOT(distributeLeft()));
169 connect(distributeCenterVToolButton, SIGNAL(clicked()), this, SLOT(distributeCenterV()));
170 connect(distributeTopToolButton, SIGNAL(clicked()), this, SLOT(distributeTop()));
171 connect(distributeAcrossPageToolButton, SIGNAL(clicked()), this, SLOT(distributeDistAcrossPage()));
172 connect(distributeDownPageToolButton, SIGNAL(clicked()), this, SLOT(distributeDistDownPage()));
173 connect(distributeAcrossMarginsToolButton, SIGNAL(clicked()), this, SLOT(distributeDistAcrossMargins()));
174 connect(distributeDownMarginsToolButton, SIGNAL(clicked()), this, SLOT(distributeDistDownMargins()));
175 connect(swapLeftToolButton, SIGNAL(clicked()), this, SLOT(swapLeft()));
176 connect(swapRightToolButton, SIGNAL(clicked()), this, SLOT(swapRight()));
177
178 alignRelativeToCombo->setCurrentIndex(0);
179 alignToChanged(0);
180 alignMethodChanged(0);
181 connect(alignRelativeToCombo, SIGNAL(activated(int)), this, SLOT(alignToChanged(int)));
182 connect(alignMoveOrResizeCombo, SIGNAL(activated(int)), this, SLOT(alignMethodChanged(int)));
183
184 unitRatio = 1.0;
185 guideDirection = -1;
186
187 guideInfoText = guideInfoTextNone;
188 alignGuideLineEdit->setText(guideInfoTextNone);
189 }
190
iconSetChange()191 void AlignDistributePalette::iconSetChange()
192 {
193 IconManager& im = IconManager::instance();
194
195 alignLeftOutToolButton->setIcon(im.loadIcon("22/align-horizontal-left-out.png"));
196 alignLeftInToolButton->setIcon(im.loadIcon("22/align-horizontal-left.png"));
197 alignCenterHorToolButton->setIcon(im.loadIcon("22/align-horizontal-center.png"));
198 alignRightInToolButton->setIcon(im.loadIcon("22/align-horizontal-right.png"));
199 alignRightOutToolButton->setIcon(im.loadIcon("22/align-horizontal-right-out.png"));
200
201 alignTopOutToolButton->setIcon(im.loadIcon("22/align-vertical-top-out.png"));
202 alignTopInToolButton->setIcon(im.loadIcon("22/align-vertical-top.png"));
203 alignCenterVerToolButton->setIcon(im.loadIcon("22/align-vertical-center.png"));
204 alignBottomInToolButton->setIcon(im.loadIcon("22/align-vertical-bottom.png"));
205 alignBottomOutToolButton->setIcon(im.loadIcon("22/align-vertical-bottom-out.png"));
206
207 distributeLeftToolButton->setIcon(im.loadIcon("22/distribute-horizontal-left.png"));
208 distributeCenterHToolButton->setIcon(im.loadIcon("22/distribute-horizontal-center.png"));
209 distributeRightToolButton->setIcon(im.loadIcon("22/distribute-horizontal-right.png"));
210 distributeDistHToolButton->setIcon(im.loadIcon("22/distribute-horizontal-equal.png"));
211
212 distributeBottomToolButton->setIcon(im.loadIcon("22/distribute-vertical-bottom.png"));
213 distributeCenterVToolButton->setIcon(im.loadIcon("22/distribute-vertical-center.png"));
214 distributeTopToolButton->setIcon(im.loadIcon("22/distribute-vertical-top.png"));
215 distributeDistVToolButton->setIcon(im.loadIcon("22/distribute-vertical-equal.png"));
216
217 distributeAcrossPageToolButton->setIcon(im.loadIcon("22/distribute-horizontal-page.png"));
218 distributeDownPageToolButton->setIcon(im.loadIcon("22/distribute-vertical-page.png"));
219 distributeAcrossMarginsToolButton->setIcon(im.loadIcon("22/distribute-horizontal-margin.png"));
220 distributeDownMarginsToolButton->setIcon(im.loadIcon("22/distribute-vertical-margin.png"));
221 distributeDistValueHToolButton->setIcon(im.loadIcon("22/distribute-horizontal-x.png"));
222 distributeDistValueVToolButton->setIcon(im.loadIcon("22/distribute-vertical-y.png"));
223
224 swapLeftToolButton->setIcon(im.loadIcon("22/swap-left.png"));
225 swapRightToolButton->setIcon(im.loadIcon("22/swap-right.png"));
226 }
227
unitChange()228 void AlignDistributePalette::unitChange()
229 {
230 if (currDoc != nullptr)
231 {
232 unitRatio = unitGetRatioFromIndex(currDoc->unitIndex());
233 distributeDistSpinBox->setNewUnit(currDoc->unitIndex());
234 enableGuideButtons();
235 }
236 }
237
setDoc(ScribusDoc * newDoc)238 void AlignDistributePalette::setDoc(ScribusDoc* newDoc)
239 {
240 currDoc = newDoc;
241 if (currDoc != nullptr)
242 alignObjects = &(currDoc->AObjects);
243 else
244 alignObjects = nullptr;
245 unitChange();
246 }
247
alignLeftOut()248 void AlignDistributePalette::alignLeftOut()
249 {
250 if (currDoc != nullptr)
251 currDoc->itemSelection_AlignLeftOut(currAlignTo, currAlignMethod, guidePosition);
252 }
253
alignLeftIn()254 void AlignDistributePalette::alignLeftIn()
255 {
256 if (currDoc != nullptr)
257 currDoc->itemSelection_AlignLeftIn(currAlignTo, currAlignMethod, guidePosition);
258 }
259
alignCenterHor()260 void AlignDistributePalette::alignCenterHor()
261 {
262 if (currDoc != nullptr)
263 currDoc->itemSelection_AlignCenterHor(currAlignTo, currAlignMethod, guidePosition);
264 }
265
alignRightIn()266 void AlignDistributePalette::alignRightIn()
267 {
268 if (currDoc != nullptr)
269 currDoc->itemSelection_AlignRightIn(currAlignTo, currAlignMethod, guidePosition);
270 }
271
alignRightOut()272 void AlignDistributePalette::alignRightOut()
273 {
274 if (currDoc != nullptr)
275 currDoc->itemSelection_AlignRightOut(currAlignTo, currAlignMethod, guidePosition);
276 }
277
alignTopOut()278 void AlignDistributePalette::alignTopOut()
279 {
280 if (currDoc != nullptr)
281 currDoc->itemSelection_AlignTopOut(currAlignTo, currAlignMethod, guidePosition);
282 }
283
alignTopIn()284 void AlignDistributePalette::alignTopIn()
285 {
286 if (currDoc != nullptr)
287 currDoc->itemSelection_AlignTopIn(currAlignTo, currAlignMethod, guidePosition);
288 }
289
290
alignCenterVer()291 void AlignDistributePalette::alignCenterVer()
292 {
293 if (currDoc != nullptr)
294 currDoc->itemSelection_AlignCenterVer(currAlignTo, currAlignMethod, guidePosition);
295 }
296
297
alignBottomIn()298 void AlignDistributePalette::alignBottomIn()
299 {
300 if (currDoc != nullptr)
301 currDoc->itemSelection_AlignBottomIn(currAlignTo, currAlignMethod, guidePosition);
302 }
303
alignBottomOut()304 void AlignDistributePalette::alignBottomOut()
305 {
306 if (currDoc != nullptr)
307 currDoc->itemSelection_AlignBottomOut(currAlignTo, currAlignMethod, guidePosition);
308 }
309
distributeLeft()310 void AlignDistributePalette::distributeLeft()
311 {
312 if (currDoc != nullptr)
313 currDoc->itemSelection_DistributeLeft();
314 }
315
distributeCenterH()316 void AlignDistributePalette::distributeCenterH()
317 {
318 if (currDoc != nullptr)
319 currDoc->itemSelection_DistributeCenterH();
320 }
321
distributeRight()322 void AlignDistributePalette::distributeRight()
323 {
324 if (currDoc != nullptr)
325 currDoc->itemSelection_DistributeRight();
326 }
327
distributeDistH(bool usingDistance)328 void AlignDistributePalette::distributeDistH(bool usingDistance)
329 {
330 if (currDoc != nullptr)
331 currDoc->itemSelection_DistributeDistH(usingDistance, distributeDistSpinBox->value(), reverseDistributionCheckBox->isChecked());
332 }
333
distributeDistValH()334 void AlignDistributePalette::distributeDistValH()
335 {
336 distributeDistSpinBox->interpretText();
337 if (currDoc != nullptr)
338 distributeDistH(true);
339 }
340
distributeDistAcrossPage()341 void AlignDistributePalette::distributeDistAcrossPage()
342 {
343 if (currDoc != nullptr)
344 currDoc->itemSelection_DistributeAcrossPage();
345 }
346
distributeDistDownPage()347 void AlignDistributePalette::distributeDistDownPage()
348 {
349 if (currDoc != nullptr)
350 currDoc->itemSelection_DistributeDownPage();
351 }
352
distributeDistAcrossMargins()353 void AlignDistributePalette::distributeDistAcrossMargins()
354 {
355 if (currDoc != nullptr)
356 currDoc->itemSelection_DistributeAcrossPage(true);
357 }
358
distributeDistDownMargins()359 void AlignDistributePalette::distributeDistDownMargins()
360 {
361 if (currDoc != nullptr)
362 currDoc->itemSelection_DistributeDownPage(true);
363 }
364
365
distributeBottom()366 void AlignDistributePalette::distributeBottom()
367 {
368 if (currDoc != nullptr)
369 currDoc->itemSelection_DistributeBottom();
370 }
371
distributeCenterV()372 void AlignDistributePalette::distributeCenterV()
373 {
374 if (currDoc != nullptr)
375 currDoc->itemSelection_DistributeCenterV();
376 }
377
distributeTop()378 void AlignDistributePalette::distributeTop()
379 {
380 if (currDoc != nullptr)
381 currDoc->itemSelection_DistributeTop();
382 }
383
distributeDistV(bool usingDistance)384 void AlignDistributePalette::distributeDistV(bool usingDistance)
385 {
386 if (currDoc != nullptr)
387 currDoc->itemSelection_DistributeDistV(usingDistance, distributeDistSpinBox->value(), reverseDistributionCheckBox->isChecked());
388 }
389
distributeDistValV()390 void AlignDistributePalette::distributeDistValV()
391 {
392 distributeDistSpinBox->interpretText();
393 if (currDoc != nullptr)
394 distributeDistV(true);
395 }
396
swapLeft()397 void AlignDistributePalette::swapLeft()
398 {
399 if (currDoc != nullptr)
400 currDoc->itemSelection_SwapLeft();
401 }
402
swapRight()403 void AlignDistributePalette::swapRight()
404 {
405 if (currDoc != nullptr)
406 currDoc->itemSelection_SwapRight();
407 }
408
alignToChanged(int newAlignTo)409 void AlignDistributePalette::alignToChanged(int newAlignTo)
410 {
411 currAlignTo = ScribusDoc::AlignTo(newAlignTo);
412 enableGuideButtons();
413 }
alignMethodChanged(int newAlignMethod)414 void AlignDistributePalette::alignMethodChanged(int newAlignMethod)
415 {
416 currAlignMethod = ScribusDoc::AlignMethod(newAlignMethod);
417 enableGuideButtons();
418 }
419
setGuide(int direction,qreal position)420 void AlignDistributePalette::setGuide(int direction, qreal position)
421 {
422 //direction 0=H, 1=V
423 // qDebug()<<"AlignDistributePalette::setGuide("<<direction<<""<<position<<")";
424 guideDirection = direction;
425 guidePosition = position;
426 enableGuideButtons();
427 }
428
429
localeChange()430 void AlignDistributePalette::localeChange()
431 {
432 const QLocale& l(LocaleManager::instance().userPreferredLocale());
433 distributeDistSpinBox->setLocale(l);
434 }
435
enableGuideButtons()436 void AlignDistributePalette::enableGuideButtons()
437 {
438 QString suffix;
439 double unitRatio = 1.0;
440 int precision = 1;
441 if (currDoc != nullptr)
442 {
443 suffix = unitGetSuffixFromIndex(currDoc->unitIndex());
444 unitRatio = unitGetRatioFromIndex(currDoc->unitIndex());
445 precision = unitGetPrecisionFromIndex(currDoc->unitIndex());
446 }
447 bool setterH = true, setterV = true;
448 switch (guideDirection)
449 {
450 case -1:
451 guideInfoText = guideInfoTextNone;
452 if (currAlignTo == ScribusDoc::alignGuide)
453 setterH = setterV = false;
454 break;
455 case 0:
456 guideInfoText = tr("Y: %1%2").arg(guidePosition * unitRatio, 0, 'f', precision).arg(suffix);
457 if (currAlignTo == ScribusDoc::alignGuide)
458 {
459 setterV = false;
460 setterH = true;
461 }
462 break;
463 case 1:
464 guideInfoText = tr("X: %1%2").arg(guidePosition * unitRatio, 0, 'f', precision).arg(suffix);
465 if (currAlignTo == ScribusDoc::alignGuide)
466 {
467 setterV = true;
468 setterH = false;
469 }
470 break;
471 }
472 bool setterO = true;
473 if (currAlignTo == ScribusDoc::alignGuide)
474 setterO = false;
475
476 alignLeftInToolButton->setEnabled(setterV);
477 alignLeftOutToolButton->setEnabled(setterO);
478 alignRightInToolButton->setEnabled(setterV);
479 alignRightOutToolButton->setEnabled(setterO);
480 alignCenterHorToolButton->setEnabled(setterV);
481
482 alignTopInToolButton->setEnabled(setterH);
483 alignTopOutToolButton->setEnabled(setterO);
484 alignBottomInToolButton->setEnabled(setterH);
485 alignBottomOutToolButton->setEnabled(setterO);
486 alignCenterVerToolButton->setEnabled(setterH);
487
488 alignGuideLineEdit->setText(guideInfoText);
489 }
490