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  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  ***************************************************************************/
15 
16 
17 #include <QCheckBox>
18 #include <QComboBox>
19 #include <QFrame>
20 #include <QGridLayout>
21 #include <QGroupBox>
22 #include <QHBoxLayout>
23 #include <QVBoxLayout>
24 #include <QLabel>
25 #include <QLineEdit>
26 #include <QPixmap>
27 #include <QPushButton>
28 #include <QSignalBlocker>
29 #include <QSpacerItem>
30 #include <QStackedWidget>
31 #include <QStringList>
32 
33 #include "annota.h"
34 #include "commonstrings.h"
35 #include "navigator.h"
36 #include "prefsmanager.h"
37 #include "prefsfile.h"
38 #include "pageitem.h"
39 #include "scfonts.h"
40 #include "scribusdoc.h"
41 #include "scribusview.h"
42 #include "util_formats.h"
43 #include "ui/customfdialog.h"
44 #include "ui/scrspinbox.h"
45 
Annota(QWidget * parent,PageItem * it,ScribusDoc * doc,ScribusView * view)46 Annota::Annota(QWidget* parent, PageItem *it, ScribusDoc* doc, ScribusView* view) :
47 	QDialog(parent),
48 	m_item(it),
49 	m_doc(doc),
50 	m_view(view)
51 {
52 	setModal(true);
53 	setWindowTitle( tr( "Annotation Properties" ) );
54 
55 	m_pageCount = m_doc->DocPages.count(),
56 	m_width = static_cast<int>(m_doc->pageWidth());
57 	m_height = static_cast<int>(m_doc->pageHeight());
58 	m_oriWidth = static_cast<int>(m_doc->pageWidth());
59 	m_oriHeight = static_cast<int>(m_doc->pageHeight());
60 
61 	QStringList tl;
62 	if ((m_item->annotation().ActionType() == Annotation::Action_GoTo) || (m_item->annotation().ActionType() == Annotation::Action_GoToR_FileRel) || (m_item->annotation().ActionType() == Annotation::Action_GoToR_FileAbs))
63 	{
64 		QString tm = m_item->annotation().Action();
65 		tl = tm.split(" ", Qt::SkipEmptyParts);
66 	}
67 	else
68 	{
69 		tl.append("0");
70 		tl.append(QString::number(m_height));
71 	}
72 
73 	AnnotLayout = new QVBoxLayout( this );
74 	AnnotLayout->setSpacing(6);
75 	AnnotLayout->setContentsMargins(9, 9, 9, 9);
76 
77 	Layout1 = new QHBoxLayout;
78 	Layout1->setSpacing(6);
79 	Layout1->setContentsMargins(0, 0, 0, 0);
80 
81 	typeCombo = new QComboBox(this);
82 	if (!m_view->m_doc->masterPageMode())
83 		typeCombo->addItem( tr("Text"));
84 	typeCombo->addItem( tr("Link"));
85 	typeCombo->addItem( tr("External Link"));
86 	typeCombo->addItem( tr("External Web-Link"));
87 	typeCombo->setEditable(false);
88 	typeComboLabel = new QLabel( tr("&Type:"), this);
89 	typeComboLabel->setBuddy(typeCombo);
90 	Layout1->addWidget( typeComboLabel );
91 	Layout1->addWidget( typeCombo );
92 	AnnotLayout->addLayout( Layout1 );
93 	if (m_view->m_doc->masterPageMode())
94 	{
95 		if (m_item->annotation().Type() < 2)
96 			typeCombo->setCurrentIndex(m_item->annotation().Type() - 1);
97 		else
98 			typeCombo->setCurrentIndex(m_item->annotation().Type() - 11);
99 		if ((m_item->annotation().ActionType() == Annotation::Action_GoToR_FileRel) || (m_item->annotation().ActionType() == Annotation::Action_URI))
100 			typeCombo->setCurrentIndex(m_item->annotation().ActionType() - 6);
101 		if (m_item->annotation().ActionType() == Annotation::Action_GoToR_FileAbs)
102 			typeCombo->setCurrentIndex(1);
103 	}
104 	else
105 	{
106 		if (m_item->annotation().Type() < 2)
107 			typeCombo->setCurrentIndex(m_item->annotation().Type());
108 		else
109 			typeCombo->setCurrentIndex(m_item->annotation().Type() - 10);
110 		if ((m_item->annotation().ActionType() == Annotation::Action_GoToR_FileRel) || (m_item->annotation().ActionType() == Annotation::Action_URI))
111 			typeCombo->setCurrentIndex(m_item->annotation().ActionType() - 5);
112 		if (m_item->annotation().ActionType() == Annotation::Action_GoToR_FileAbs)
113 			typeCombo->setCurrentIndex(2);
114 	}
115 	Fram = new QStackedWidget(this);
116 	AnnotLayout->addWidget( Fram );
117 
118 //	Frame9 = new QFrame( this );
119 //	Frame9->setFrameShape( QFrame::NoFrame );
120 //	Frame9->setFrameShadow( QFrame::Plain );
121 
122 	GroupBox2 = new QGroupBox( this );
123 	GroupBox2->setTitle( tr( "Options" ) );
124 	GroupBox2Layout = new QGridLayout( GroupBox2 );
125 	GroupBox2Layout->setAlignment( Qt::AlignTop );
126 	GroupBox2Layout->setSpacing(6);
127 	GroupBox2Layout->setContentsMargins(9, 9, 9, 9);
128 	iconComboLabel = new QLabel( tr("Icon:"), GroupBox2);
129 	iconCombo = new QComboBox(GroupBox2);
130 	iconCombo->addItem( tr("Note"));
131 	iconCombo->addItem( tr("Comment"));
132 	iconCombo->addItem( tr("Key"));
133 	iconCombo->addItem( tr("Help"));
134 	iconCombo->addItem( tr("New Paragraph"));
135 	iconCombo->addItem( tr("Paragraph"));
136 	iconCombo->addItem( tr("Insert"));
137 	iconCombo->addItem( tr("Cross"));
138 	iconCombo->addItem( tr("Circle"));
139 	iconCombo->setEditable(false);
140 	iconCombo->setCurrentIndex(m_item->annotation().Icon());
141 	GroupBox2Layout->addWidget( iconComboLabel, 0, 0 );
142 	GroupBox2Layout->addWidget( iconCombo, 0, 1 );
143 	textIsOpen = new QCheckBox( tr("Annotation is Open"), GroupBox2);
144 	textIsOpen->setChecked(m_item->annotation().IsAnOpen());
145 	GroupBox2Layout->addWidget( textIsOpen, 1, 0, 1, 1 );
146 	Fram->addWidget(GroupBox2);
147 
148 	GroupBox1 = new QGroupBox( this );
149 	GroupBox1->setTitle( tr( "Destination" ) );
150 	GroupBox1Layout = new QGridLayout( GroupBox1 );
151 	GroupBox1Layout->setAlignment( Qt::AlignTop );
152 	GroupBox1Layout->setSpacing(6);
153 	GroupBox1Layout->setContentsMargins(9, 9, 9, 9);
154 
155 	destFile = new QLineEdit(GroupBox1);
156 	destFile->setText(m_item->annotation().Extern());
157 	destFile->setReadOnly(true);
158 	GroupBox1Layout->addWidget( destFile, 0, 0, 1, 2 );
159 	changeFile = new QPushButton(GroupBox1);
160 	changeFile->setText( tr("C&hange..."));
161 	GroupBox1Layout->addWidget( changeFile, 0, 2 );
162 	useAbsolute = new QCheckBox( tr("Export absolute Filename"), GroupBox1);
163 	GroupBox1Layout->addWidget( useAbsolute, 1, 0, 1, 3 );
164 	if (m_item->annotation().ActionType() == Annotation::Action_GoToR_FileRel)
165 		useAbsolute->setChecked(false);
166 	else if (m_item->annotation().ActionType() == Annotation::Action_GoToR_FileAbs)
167 		useAbsolute->setChecked(true);
168 	if ((m_item->annotation().ActionType() != Annotation::Action_GoToR_FileRel) && (m_item->annotation().ActionType() != Annotation::Action_URI) && (m_item->annotation().ActionType() != Annotation::Action_GoToR_FileAbs))
169 	{
170 		destFile->hide();
171 		changeFile->hide();
172 		useAbsolute->hide();
173 	}
174 
175 	pageSpin = new ScrSpinBox( GroupBox1);
176 	pageSpin->setDecimals(0);
177 	pageSpin->setMinimum(1);
178 	pageSpin->setMaximum(((m_item->annotation().ActionType() == Annotation::Action_GoToR_FileRel) || (m_item->annotation().ActionType() == Annotation::Action_GoToR_FileAbs)) ? 1000 : m_pageCount);
179 	pageSpin->setSuffix(QString());
180 	pageSpinLabel = new QLabel( tr("&Page:"), GroupBox1);
181 	pageSpinLabel->setBuddy(pageSpin);
182 	GroupBox1Layout->addWidget( pageSpinLabel, 2, 0 );
183 	GroupBox1Layout->addWidget( pageSpin, 2, 1 );
184 	if ((!destFile->text().isEmpty()) && ((m_item->annotation().ActionType() == Annotation::Action_GoToR_FileRel) || (m_item->annotation().ActionType() == Annotation::Action_GoToR_FileAbs)))
185 		navigator = new Navigator( GroupBox1, 100, m_item->annotation().Ziel() + 1, m_view, m_item->annotation().Extern());
186 	else
187 	{
188 		int targetPage = m_item->annotation().Ziel();
189 		if ((targetPage >= 0) && (targetPage < m_view->m_doc->Pages->count()))
190 			navigator = new Navigator( GroupBox1, 100, m_item->annotation().Ziel(), m_view);
191 		else
192 		{
193 			m_item->annotation().setZiel(m_view->m_doc->currentPageNumber());
194 			navigator = new Navigator( GroupBox1, 100, m_item->annotation().Ziel(), m_view);
195 		}
196 	}
197 	pageSpin->setValue(m_item->annotation().Ziel() + 1);
198 	navigator->setMinimumSize(QSize(navigator->pmx.width(), navigator->pmx.height()));
199 	GroupBox1Layout->addWidget(navigator, 2, 2, 3, 1);
200 
201 	xSpin = new ScrSpinBox( GroupBox1);
202 	xSpin->setDecimals(0);
203 	xSpin->setSuffix( tr( " pt" ) );
204 	xSpin->setMaximum(m_width);
205 	xSpin->setValue(tl[0].toInt());
206 	xSpinLabel = new QLabel( tr("&X-Pos:"), GroupBox1 );
207 	xSpinLabel->setBuddy(xSpin);
208 	GroupBox1Layout->addWidget( xSpinLabel, 3, 0 );
209 	GroupBox1Layout->addWidget( xSpin, 3, 1 );
210 	ySpin = new ScrSpinBox( GroupBox1 );
211 	ySpin->setDecimals(0);
212 	ySpin->setMaximum(m_height);
213 	ySpin->setSuffix( tr( " pt" ) );
214 	ySpin->setValue(m_height - tl[1].toInt());
215 	ySpinLabel = new QLabel( tr("&Y-Pos:"), GroupBox1 );
216 	ySpinLabel->setBuddy(ySpin);
217 	GroupBox1Layout->addWidget( ySpinLabel, 4, 0 );
218 	GroupBox1Layout->addWidget( ySpin, 4, 1 );
219 	Fram->addWidget(GroupBox1);
220 
221 	Layout1_2 = new QHBoxLayout;
222 	Layout1_2->setSpacing(6);
223 	Layout1_2->setContentsMargins(0, 0, 0, 0);
224 
225 	QSpacerItem* spacer = new QSpacerItem( 2, 2, QSizePolicy::Expanding, QSizePolicy::Minimum );
226 	Layout1_2->addItem( spacer );
227 	okButton = new QPushButton( CommonStrings::tr_OK, this );
228 	okButton->setDefault( true );
229 	Layout1_2->addWidget( okButton );
230 	cancelButton = new QPushButton( CommonStrings::tr_Cancel, this );
231 	Layout1_2->addWidget( cancelButton );
232 	AnnotLayout->addLayout( Layout1_2 );
233 
234 	connect(okButton, SIGNAL(clicked()), this, SLOT(SetValues()));
235 	connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
236 	connect(typeCombo, SIGNAL(activated(int)), this, SLOT(SetTarget(int)));
237 	connect(pageSpin, SIGNAL(valueChanged(double)), this, SLOT(SetPage(double)));
238 	connect(navigator, SIGNAL(Coords(double, double)), this, SLOT(SetCoords(double, double)));
239 	connect(xSpin, SIGNAL(valueChanged(double)), this, SLOT(SetCross()));
240 	connect(ySpin, SIGNAL(valueChanged(double)), this, SLOT(SetCross()));
241 	connect(changeFile, SIGNAL(clicked()), this, SLOT(GetFile()));
242 	if (m_view->m_doc->masterPageMode())
243 		SetTarget(m_item->annotation().Type() - 1);
244 	else
245 		SetTarget(m_item->annotation().Type());
246 	SetCross();
247 }
248 
SetCoords(double x,double y)249 void Annota::SetCoords(double x, double y)
250 {
251 	xSpin->setValue(static_cast<int>(x * m_width));
252 	ySpin->setValue(static_cast<int>(y * m_height));
253 }
254 
SetPage(double v)255 void Annota::SetPage(double v)
256 {
257 	QSignalBlocker spinBox1Blocker(pageSpin);
258 
259 	int link = m_view->m_doc->masterPageMode() ? 1 : 2;
260 	if (typeCombo->currentIndex() == link)
261 	{
262 		if (!navigator->setPage(static_cast<int>(v), 100, destFile->text()))
263 		{
264 			pageSpin->setValue(1);
265 			navigator->setPage(1, 100, destFile->text());
266 		}
267 		m_width = navigator->Width;
268 		m_height = navigator->Height;
269 	}
270 	else
271 	{
272 		navigator->setPage(qMin(static_cast<int>(v) - 1, m_pageCount - 1), 100);
273 		pageSpin->setValue(qMin(static_cast<int>(v), m_pageCount));
274 		m_width = m_oriWidth;
275 		m_height = m_oriHeight;
276 	}
277 	xSpin->setMaximum(m_width);
278 	ySpin->setMaximum(m_height);
279 }
280 
SetCross()281 void Annota::SetCross()
282 {
283 	int x,y;
284 	disconnect(navigator, SIGNAL(Coords(double, double)), this, SLOT(SetCoords(double, double)));
285 	x = static_cast<int>(xSpin->value() / static_cast<double>(m_width) * navigator->pmx.width());
286 	y = static_cast<int>(ySpin->value() / static_cast<double>(m_height) * navigator->pmx.height());
287 	navigator->drawMark(x, y);
288 	connect(navigator, SIGNAL(Coords(double, double)), this, SLOT(SetCoords(double, double)));
289 }
290 
SetValues()291 void Annota::SetValues()
292 {
293 	QString tmp, tmp2;
294 	m_item->annotation().setZiel(pageSpin->value() - 1);
295 	if (m_view->m_doc->masterPageMode())
296 		m_item->annotation().setType(typeCombo->currentIndex() + 11);
297 	else
298 		m_item->annotation().setType(typeCombo->currentIndex() + 10);
299 	switch (m_item->annotation().Type())
300 	{
301 	case 10:
302 		m_item->annotation().setActionType(Annotation::Action_None);
303 		m_item->annotation().setAnOpen(textIsOpen->isChecked());
304 		m_item->annotation().setIcon(iconCombo->currentIndex());
305 		break;
306 	case 11:
307 		m_item->annotation().setAction(tmp.setNum(xSpin->value()) + " " + tmp2.setNum(m_height - ySpin->value()) + " 0");
308 		m_item->annotation().setExtern("");
309 		m_item->annotation().setActionType(Annotation::Action_GoTo);
310 		break;
311 	case 12:
312 		m_item->annotation().setAction(tmp.setNum(xSpin->value()) + " " + tmp2.setNum(m_height - ySpin->value()) + " 0");
313 		if (!destFile->text().isEmpty())
314 		{
315 			m_item->annotation().setExtern(destFile->text());
316 			if (useAbsolute->isChecked())
317 				m_item->annotation().setActionType(Annotation::Action_GoToR_FileAbs);
318 			else
319 				m_item->annotation().setActionType(Annotation::Action_GoToR_FileRel);
320 		}
321 		m_item->annotation().setType(Annotation::Link);
322 		break;
323 	case 13:
324 		m_item->annotation().setAction("");
325 		if (!destFile->text().isEmpty())
326 		{
327 			m_item->annotation().setExtern(destFile->text());
328 			m_item->annotation().setActionType(Annotation::Action_URI);
329 		}
330 		m_item->annotation().setType(Annotation::Link);
331 		break;
332 	}
333 	accept();
334 }
335 
SetTarget(int it)336 void Annota::SetTarget(int it)
337 {
338 	int a = it;
339 	disconnect(typeCombo, SIGNAL(activated(int)), this, SLOT(SetTarget(int)));
340 	if (m_view->m_doc->masterPageMode())
341 		a++;
342 	navigator->show();
343 	pageSpinLabel->show();
344 	xSpinLabel->show();
345 	ySpinLabel->show();
346 	pageSpin->show();
347 	xSpin->show();
348 	ySpin->show();
349 	switch (a)
350 	{
351 	case 1:
352 		Fram->setCurrentIndex(1);
353 		destFile->setText("");
354 		destFile->hide();
355 		changeFile->hide();
356 		useAbsolute->hide();
357 		m_item->annotation().setActionType(Annotation::Action_GoTo);
358 		SetPage(qMin(static_cast<int>(pageSpin->value()), m_pageCount));
359 		break;
360 	case 2:
361 		Fram->setCurrentIndex(1);
362 		destFile->show();
363 		changeFile->show();
364 		useAbsolute->show();
365 		destFile->setReadOnly(true);
366 		if ((destFile->text().isEmpty())  || (m_item->annotation().ActionType() == Annotation::Action_URI))
367 		{
368 			destFile->setText("");
369 			GetFile();
370 		}
371 		if (destFile->text().isEmpty())
372 		{
373 			m_item->annotation().setActionType(Annotation::Action_GoTo);
374 			destFile->setText("");
375 			destFile->hide();
376 			changeFile->hide();
377 			useAbsolute->hide();
378 			if (m_view->m_doc->masterPageMode())
379 				typeCombo->setCurrentIndex(0);
380 			else
381 				typeCombo->setCurrentIndex(1);
382 		}
383 		else
384 		{
385 			if (useAbsolute->isChecked())
386 				m_item->annotation().setActionType(Annotation::Action_GoToR_FileAbs);
387 			else
388 				m_item->annotation().setActionType(Annotation::Action_GoToR_FileRel);
389 		}
390 		SetPage(qMin(static_cast<int>(pageSpin->value()), m_pageCount));
391 		break;
392 	case 3:
393 		Fram->setCurrentIndex(1);
394 		destFile->show();
395 		destFile->setReadOnly(false);
396 		changeFile->hide();
397 		useAbsolute->hide();
398 		navigator->hide();
399 		pageSpinLabel->hide();
400 		xSpinLabel->hide();
401 		ySpinLabel->hide();
402 		pageSpin->hide();
403 		xSpin->hide();
404 		ySpin->hide();
405 		m_item->annotation().setActionType(Annotation::Action_URI);
406 		break;
407 	case 11:
408 		Fram->setCurrentIndex(1);
409 		if ((m_item->annotation().ActionType() == Annotation::Action_GoToR_FileRel) || (m_item->annotation().ActionType() == Annotation::Action_GoToR_FileAbs))
410 		{
411 			destFile->show();
412 			changeFile->show();
413 			useAbsolute->show();
414 			destFile->setReadOnly(true);
415 		}
416 		if (m_item->annotation().ActionType() == Annotation::Action_URI)
417 		{
418 			destFile->show();
419 			destFile->setReadOnly(false);
420 			changeFile->hide();
421 			useAbsolute->hide();
422 			navigator->hide();
423 			pageSpinLabel->hide();
424 			xSpinLabel->hide();
425 			ySpinLabel->hide();
426 			pageSpin->hide();
427 			xSpin->hide();
428 			ySpin->hide();
429 		}
430 		if (navigator->isVisible())
431 			SetPage(qMin(static_cast<int>(pageSpin->value()), m_pageCount));
432 		break;
433 	default:
434 		Fram->setCurrentIndex(0);
435 		break;
436 	}
437 	connect(typeCombo, SIGNAL(activated(int)), this, SLOT(SetTarget(int)));
438 }
439 
GetFile()440 void Annota::GetFile()
441 {
442 	PrefsContext* dirs = PrefsManager::instance().prefsFile->getContext("dirs");
443 	QString wdir = dirs->get("annot_getfile", ".");
444 
445 	CustomFDialog dia(this, wdir, tr("Open"), tr("%1;;All Files (*)").arg(FormatsManager::instance()->extensionsForFormat(FormatsManager::PDF)));
446 	if (!destFile->text().isEmpty())
447 		dia.setSelection(destFile->text());
448 	if (dia.exec() != QDialog::Accepted)
449 		return;
450 
451 	QString fn = dia.selectedFile();
452 	if (fn.isEmpty())
453 		return;
454 	dirs->set("annot_getfile", fn.left(fn.lastIndexOf("/")));
455 	destFile->setText(fn);
456 	pageSpin->setValue(1);
457 	pageSpin->setMaximum(1000);
458 	SetPage(1);
459 }
460