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 symbolpalette.cpp - description
9 -------------------
10 begin : Sat May 8 2010
11 copyright : (C) 2010 by Franz Schmid
12 email : Franz.Schmid@altmuehlnet.de
13 ***************************************************************************/
14
15 /***************************************************************************
16 * *
17 * This program is free software; you can redistribute it and/or modify *
18 * it under the terms of the GNU General Public License as published by *
19 * the Free Software Foundation; either version 2 of the License, or *
20 * (at your option) any later version. *
21 * *
22 ***************************************************************************/
23 #include "symbolpalette.h"
24 #include <QPainter>
25 #include <QByteArray>
26 #include <QDrag>
27 #include <QMimeData>
28 #include "scpattern.h"
29 #include "scribusdoc.h"
30 #include "scribus.h"
31
SymbolView(QWidget * parent)32 SymbolView::SymbolView(QWidget* parent) : QListWidget(parent)
33 {
34 setDragEnabled(true);
35 setViewMode(QListView::IconMode);
36 setFlow(QListView::LeftToRight);
37 setSortingEnabled(true);
38 setWrapping(true);
39 setAcceptDrops(true);
40 setDropIndicatorShown(true);
41 setDragDropMode(QAbstractItemView::DragDrop);
42 setResizeMode(QListView::Adjust);
43 setSelectionMode(QAbstractItemView::SingleSelection);
44 setContextMenuPolicy(Qt::CustomContextMenu);
45 delegate = new ScListWidgetDelegate(this, this);
46 setItemDelegate(delegate);
47 setIconSize(QSize(48, 48));
48 connect(this, SIGNAL(customContextMenuRequested (const QPoint&)), this, SLOT(HandleContextMenu(QPoint)));
49 }
50
HandleContextMenu(QPoint p)51 void SymbolView::HandleContextMenu(QPoint p)
52 {
53 QListWidgetItem *item = itemAt(p);
54 if (!item)
55 {
56 QMenu *pmenu = new QMenu();
57 QAction* viewAct;
58 viewAct = pmenu->addAction( tr("Display Icons only"));
59 viewAct->setCheckable(true);
60 viewAct->setChecked(delegate->iconOnly());
61 connect(viewAct, SIGNAL(triggered()), this, SLOT(changeDisplay()));
62 pmenu->exec(QCursor::pos());
63 delete pmenu;
64 }
65 }
66
changeDisplay()67 void SymbolView::changeDisplay()
68 {
69 reset();
70 delegate->setIconOnly(!delegate->iconOnly());
71 repaint();
72 }
73
dragEnterEvent(QDragEnterEvent * e)74 void SymbolView::dragEnterEvent(QDragEnterEvent *e)
75 {
76 if (e->source() == this)
77 e->ignore();
78 else
79 e->acceptProposedAction();
80 }
81
dragMoveEvent(QDragMoveEvent * e)82 void SymbolView::dragMoveEvent(QDragMoveEvent *e)
83 {
84 if (e->source() == this)
85 e->ignore();
86 else
87 e->acceptProposedAction();
88 }
89
dropEvent(QDropEvent * e)90 void SymbolView::dropEvent(QDropEvent *e)
91 {
92 if (e->mimeData()->hasText())
93 {
94 e->acceptProposedAction();
95 if (e->source() == this)
96 return;
97 QString text = e->mimeData()->text();
98 if ((text.startsWith("<SCRIBUSELEM")) || (text.startsWith("SCRIBUSELEMUTF8")))
99 emit objectDropped();
100 }
101 else
102 e->ignore();
103 }
104
105
viewportEvent(QEvent * event)106 bool SymbolView::viewportEvent(QEvent *event)
107 {
108 if (event != nullptr)
109 {
110 if (event->type() == QEvent::ToolTip)
111 {
112 QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
113 QListWidgetItem* it = itemAt(helpEvent->pos());
114 if (it != nullptr)
115 {
116 event->accept();
117 QString tipText = it->text();
118 QToolTip::showText(helpEvent->globalPos(), tipText, this);
119 return true;
120 }
121 }
122 else if (event->type() == QEvent::MouseButtonPress)
123 {
124 QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
125 if (mouseEvent->button() == Qt::RightButton)
126 return true;
127 }
128 else if (event->type() == QEvent::MouseButtonRelease)
129 {
130 QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
131 if (mouseEvent->button() == Qt::RightButton)
132 {
133 emit customContextMenuRequested(mouseEvent->pos());
134 return true;
135 }
136 }
137 }
138 return QListWidget::viewportEvent(event);
139 }
140
startDrag(Qt::DropActions supportedActions)141 void SymbolView::startDrag(Qt::DropActions supportedActions)
142 {
143 QMimeData *mimeData = new QMimeData;
144 QByteArray data = currentItem()->text().toLocal8Bit();
145 mimeData->setData("text/symbol", data);
146 QDrag *drag = new QDrag(this);
147 drag->setMimeData(mimeData);
148 drag->setPixmap(currentItem()->icon().pixmap(48, 48));
149 drag->exec(Qt::CopyAction);
150 clearSelection();
151 }
152
SymbolPalette(QWidget * parent)153 SymbolPalette::SymbolPalette( QWidget* parent) : ScDockPalette(parent, "Symb", Qt::WindowFlags())
154 {
155 setContentsMargins(3, 3, 3, 3);
156 setMinimumSize( QSize( 220, 240 ) );
157 setObjectName(QString::fromLocal8Bit("Symb"));
158 setSizePolicy( QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
159 SymbolViewWidget = new SymbolView(this);
160 SymbolViewWidget->clear();
161 setWidget( SymbolViewWidget );
162
163 unsetDoc();
164 m_scMW = nullptr;
165 editItemNames.clear();
166 languageChange();
167 m_item = nullptr;
168 connect(SymbolViewWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(handleDoubleClick(QListWidgetItem*)));
169 connect(SymbolViewWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(handleContextMenue(QPoint)));
170 connect(SymbolViewWidget, SIGNAL(objectDropped()), this, SIGNAL(objectDropped()));
171 }
172
handleContextMenue(QPoint p)173 void SymbolPalette::handleContextMenue(QPoint p)
174 {
175 if (!m_doc)
176 return;
177 QListWidgetItem *item = SymbolViewWidget->itemAt(p);
178 if (item)
179 {
180 m_item = item;
181 QMenu *pmenu = new QMenu();
182 QAction* editAct = pmenu->addAction( tr("Edit Item"));
183 connect(editAct, SIGNAL(triggered()), this, SLOT(handleEditItem()));
184 QAction* delAct = pmenu->addAction( tr("Remove Item"));
185 connect(delAct, SIGNAL(triggered()), this, SLOT(handleDeleteItem()));
186 pmenu->exec(QCursor::pos());
187 delete pmenu;
188 }
189 }
190
handleDoubleClick(QListWidgetItem * item)191 void SymbolPalette::handleDoubleClick(QListWidgetItem *item)
192 {
193 if (item)
194 emit startEdit(item->text());
195 }
196
handleEditItem()197 void SymbolPalette::handleEditItem()
198 {
199 if (m_item != nullptr)
200 {
201 emit startEdit(m_item->text());
202 m_item = nullptr;
203 }
204 }
205
handleDeleteItem()206 void SymbolPalette::handleDeleteItem()
207 {
208 if (m_item != nullptr)
209 {
210 if (m_doc->docPatterns.contains(m_item->text()))
211 {
212 m_doc->removePattern(m_item->text());
213 updateSymbolList();
214 m_doc->regionsChanged()->update(QRect());
215 }
216 m_item = nullptr;
217 }
218 }
219
editingStart(QStringList names)220 void SymbolPalette::editingStart(QStringList names)
221 {
222 editItemNames = names;
223 for (int a = 0; a < editItemNames.count(); a++)
224 {
225 QList<QListWidgetItem*> items = SymbolViewWidget->findItems(names[a], Qt::MatchExactly);
226 if (items.count() > 0)
227 items[0]->setFlags(Qt::NoItemFlags);
228 }
229 }
230
editingFinished()231 void SymbolPalette::editingFinished()
232 {
233 editItemNames.clear();
234 updateSymbolList();
235 }
236
setMainWindow(ScribusMainWindow * mw)237 void SymbolPalette::setMainWindow(ScribusMainWindow *mw)
238 {
239 m_scMW = mw;
240 if (m_scMW == nullptr)
241 {
242 SymbolViewWidget->clear();
243 disconnect(m_scMW, SIGNAL(UpdateRequest(int)), this, SLOT(handleUpdateRequest(int)));
244 return;
245 }
246 connect(m_scMW, SIGNAL(UpdateRequest(int)), this, SLOT(handleUpdateRequest(int)), Qt::UniqueConnection);
247 }
248
setDoc(ScribusDoc * newDoc)249 void SymbolPalette::setDoc(ScribusDoc *newDoc)
250 {
251 if (m_scMW == nullptr)
252 m_doc = nullptr;
253 else
254 m_doc = newDoc;
255 if (m_doc == nullptr)
256 {
257 SymbolViewWidget->clear();
258 setEnabled(true);
259 }
260 else
261 {
262 setEnabled(!m_doc->drawAsPreview);
263 updateSymbolList();
264 }
265 }
266
unsetDoc()267 void SymbolPalette::unsetDoc()
268 {
269 m_doc = nullptr;
270 SymbolViewWidget->clear();
271 setEnabled(true);
272 }
273
handleUpdateRequest(int updateFlags)274 void SymbolPalette::handleUpdateRequest(int updateFlags)
275 {
276 if (updateFlags & reqSymbolsUpdate)
277 updateSymbolList();
278 }
279
updateSymbolList()280 void SymbolPalette::updateSymbolList()
281 {
282 SymbolViewWidget->clear();
283 SymbolViewWidget->setWordWrap(true);
284 if (!m_doc)
285 return;
286
287 QStringList patK = m_doc->docPatterns.keys();
288 patK.sort();
289 for (int a = 0; a < patK.count(); a++)
290 {
291 ScPattern sp = m_doc->docPatterns.value(patK[a]);
292 QPixmap pm;
293 if (sp.getPattern()->width() >= sp.getPattern()->height())
294 pm = QPixmap::fromImage(sp.getPattern()->scaledToWidth(48, Qt::SmoothTransformation));
295 else
296 pm = QPixmap::fromImage(sp.getPattern()->scaledToHeight(48, Qt::SmoothTransformation));
297 QPixmap pm2(48, 48);
298 pm2.fill(palette().color(QPalette::Base));
299 QPainter p;
300 p.begin(&pm2);
301 p.drawPixmap(24 - pm.width() / 2, 24 - pm.height() / 2, pm);
302 p.end();
303 QListWidgetItem *item = new QListWidgetItem(pm2, patK[a], SymbolViewWidget);
304 if (editItemNames.contains(patK[a]))
305 item->setFlags(Qt::NoItemFlags);
306 else
307 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
308 }
309 }
310
changeEvent(QEvent * e)311 void SymbolPalette::changeEvent(QEvent *e)
312 {
313 if (e->type() == QEvent::LanguageChange)
314 {
315 languageChange();
316 }
317 else
318 ScDockPalette::changeEvent(e);
319 }
320
languageChange()321 void SymbolPalette::languageChange()
322 {
323 setWindowTitle( tr( "Symbols" ) );
324 }
325
keyPressEvent(QKeyEvent * e)326 void SymbolPalette::keyPressEvent(QKeyEvent* e)
327 {
328 if (!m_doc)
329 return;
330 switch (e->key())
331 {
332 case Qt::Key_Backspace:
333 case Qt::Key_Delete:
334 {
335 QListWidgetItem* it = SymbolViewWidget->currentItem();
336 if (it != nullptr)
337 {
338 if (m_doc->docPatterns.contains(it->text()))
339 {
340 m_doc->removePattern(it->text());
341 updateSymbolList();
342 m_doc->regionsChanged()->update(QRect());
343 e->accept();
344 }
345 }
346 }
347 break;
348 default:
349 break;
350 }
351 }
352