1 /* This file is part of the KDE project
2 * Copyright (C) 2006-2007 Jan Hambrecht <jaham@gmx.net>
3 * Copyright (C) 2008-2009 Fredy Yanardi <fyanardi@gmail.com>
4 * Copyright (C) 2009 Jean-Nicolas Artaud <jeannicolasartaud@gmail.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #include "KoPADocumentStructureDocker.h"
23
24 #include "KoPADocumentModel.h"
25 #include "KoPADocument.h"
26 #include "KoPAPageBase.h"
27 #include "KoPACanvas.h"
28 #include "KoPAViewBase.h"
29
30 #include <KoShapeManager.h>
31 #include <KoToolManager.h>
32 #include <KoCanvasBase.h>
33 #include <KoCanvasController.h>
34 #include <KoSelection.h>
35 #include <KoShapeOdfSaveHelper.h>
36 #include <KoPAOdfPageSaveHelper.h>
37 #include <KoDrag.h>
38 #include <KoShapeCreateCommand.h>
39 #include <KoShapeDeleteCommand.h>
40 #include <KoShapeReorderCommand.h>
41 #include <KoShapeLayer.h>
42 #include <KoShapePaste.h>
43 #include <KoViewItemContextBar.h>
44
45 #include <KoIcon.h>
46
47 #include <KSharedConfig>
48 #include <klocalizedstring.h>
49 #include <kmessagebox.h>
50 #include <kconfiggroup.h>
51
52 #include <QMimeData>
53 #include <QMenu>
54 #include <QInputDialog>
55 #include <QGridLayout>
56 #include <QToolButton>
57 #include <QButtonGroup>
58 #include <QItemSelection>
59 #include <QApplication>
60 #include <QClipboard>
61
62 #include <algorithm>
63
64 enum ButtonIds
65 {
66 Button_Raise,
67 Button_Lower,
68 Button_Delete
69 };
70
KoPADocumentStructureDockerFactory(KoDocumentSectionView::DisplayMode mode,KoPageApp::PageType pageType)71 KoPADocumentStructureDockerFactory::KoPADocumentStructureDockerFactory(KoDocumentSectionView::DisplayMode mode, KoPageApp::PageType pageType)
72 : m_mode(mode)
73 , m_pageType(pageType)
74 {
75 }
76
id() const77 QString KoPADocumentStructureDockerFactory::id() const
78 {
79 return QString("document section view");
80 }
81
createDockWidget()82 QDockWidget* KoPADocumentStructureDockerFactory::createDockWidget()
83 {
84 return new KoPADocumentStructureDocker(m_mode, m_pageType);
85 }
86
KoPADocumentStructureDocker(KoDocumentSectionView::DisplayMode mode,KoPageApp::PageType pageType,QWidget * parent)87 KoPADocumentStructureDocker::KoPADocumentStructureDocker(KoDocumentSectionView::DisplayMode mode, KoPageApp::PageType pageType, QWidget* parent)
88 : QDockWidget(parent)
89 , KoCanvasObserverBase()
90 , m_doc(0)
91 , m_model(0)
92 {
93 setWindowTitle(i18n("Document"));
94
95 QWidget *mainWidget = new QWidget(this);
96 QGridLayout* layout = new QGridLayout(mainWidget);
97 layout->addWidget(m_sectionView = new KoDocumentSectionView(mainWidget), 0, 0, 1, -1);
98
99 QToolButton *button = new QToolButton(mainWidget);
100 button->setIcon(koIcon("list-add"));
101 if (pageType == KoPageApp::Slide) {
102 button->setToolTip(i18n("Add a new slide or layer"));
103 }
104 else {
105 button->setToolTip(i18n("Add a new page or layer"));
106 }
107 layout->addWidget(button, 1, 0);
108
109 QMenu *menu = new QMenu(button);
110 button->setMenu(menu);
111 button->setPopupMode(QToolButton::InstantPopup);
112 menu->addAction(koIcon("document-new"),
113 (pageType == KoPageApp::Slide) ? i18n("Slide") : i18n("Page"),
114 this, SLOT(addPage()));
115 m_addLayerAction = menu->addAction(koIcon("layer-new"), i18n("Layer"), this, SLOT(addLayer()));
116
117 m_buttonGroup = new QButtonGroup(mainWidget);
118 m_buttonGroup->setExclusive(false);
119
120 button = new QToolButton(mainWidget);
121 button->setIcon(koIcon("list-remove"));
122 button->setToolTip(i18n("Delete selected objects"));
123 m_buttonGroup->addButton(button, Button_Delete);
124 layout->addWidget(button, 1, 1);
125
126 button = new QToolButton(mainWidget);
127 button->setIcon(koIcon("arrow-up"));
128 button->setToolTip(i18n("Raise selected objects"));
129 m_buttonGroup->addButton(button, Button_Raise);
130 layout->addWidget(button, 1, 3);
131
132 button = new QToolButton(mainWidget);
133 button->setIcon(koIcon("arrow-down"));
134 button->setToolTip(i18n("Lower selected objects"));
135 m_buttonGroup->addButton(button, Button_Lower);
136 layout->addWidget(button, 1, 4);
137
138 button = new QToolButton(mainWidget);
139 menu = new QMenu(this);
140 QActionGroup *group = new QActionGroup(this);
141
142 m_viewModeActions.insert(KoDocumentSectionView::MinimalMode,
143 menu->addAction(koIcon("view-list-text"), i18n("Minimal View"), this, SLOT(minimalView())));
144 m_viewModeActions.insert(KoDocumentSectionView::DetailedMode,
145 menu->addAction(koIcon("view-list-details"), i18n("Detailed View"), this, SLOT(detailedView())));
146 m_viewModeActions.insert(KoDocumentSectionView::ThumbnailMode,
147 menu->addAction(koIcon("view-preview"), i18n("Thumbnail View"), this, SLOT(thumbnailView())));
148
149 foreach (QAction* action, m_viewModeActions) {
150 action->setCheckable(true);
151 action->setActionGroup(group);
152 }
153
154 button->setMenu(menu);
155 button->setPopupMode(QToolButton::InstantPopup);
156 button->setIcon(koIcon("view-choose"));
157 button->setText(i18n("View mode"));
158 layout->addWidget(button, 1, 5);
159
160 layout->setSpacing(0);
161 layout->setMargin(3);
162 layout->setColumnStretch(2, 10);
163
164 setWidget(mainWidget);
165
166 connect(m_buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotButtonClicked(int)));
167
168 m_model = new KoPADocumentModel(this);
169 m_sectionView->setModel(m_model);
170 m_sectionView->setSelectionBehavior(QAbstractItemView::SelectRows);
171 m_sectionView->setSelectionMode(QAbstractItemView::ExtendedSelection);
172 m_sectionView->setDragDropMode(QAbstractItemView::InternalMove);
173
174 connect(m_sectionView, SIGNAL(pressed(QModelIndex)), this, SLOT(itemClicked(QModelIndex)));
175 connect(m_sectionView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
176 this, SLOT(itemSelected(QItemSelection,QItemSelection)));
177
178 connect(m_model, SIGNAL(requestPageSelection(int,int)), this, SLOT(selectPages(int,int)));
179 connect(m_model, SIGNAL(modelReset()), this, SIGNAL(dockerReset()));
180
181 KConfigGroup configGroup = KSharedConfig::openConfig()->group("KoPageApp/DocumentStructureDocker");
182 QString viewModeString = configGroup.readEntry("ViewMode", "");
183
184 if (viewModeString.isEmpty())
185 setViewMode(mode);
186 else
187 setViewMode(viewModeFromString(viewModeString));
188
189 m_itemsContextBar = new KoViewItemContextBar(m_sectionView);
190 }
191
~KoPADocumentStructureDocker()192 KoPADocumentStructureDocker::~KoPADocumentStructureDocker()
193 {
194 KConfigGroup configGroup = KSharedConfig::openConfig()->group("KoPageApp/DocumentStructureDocker");
195 configGroup.writeEntry("ViewMode", viewModeToString(m_sectionView->displayMode()));
196 }
197
updateView()198 void KoPADocumentStructureDocker::updateView()
199 {
200 m_model->update();
201 }
202
slotButtonClicked(int buttonId)203 void KoPADocumentStructureDocker::slotButtonClicked(int buttonId)
204 {
205 switch (buttonId)
206 {
207 case Button_Raise:
208 raiseItem();
209 break;
210 case Button_Lower:
211 lowerItem();
212 break;
213 case Button_Delete:
214 deleteItem();
215 break;
216 }
217 }
218
itemClicked(const QModelIndex & index)219 void KoPADocumentStructureDocker::itemClicked(const QModelIndex &index)
220 {
221 Q_ASSERT(index.internalPointer());
222
223 if (!index.isValid())
224 return;
225
226 KoShape *shape = static_cast<KoShape*>(index.internalPointer());
227 if (!shape)
228 return;
229 // check whether the newly selected shape is a page or shape/layer
230 bool isPage = (dynamic_cast<KoPAPageBase *>(shape) != 0);
231 KoCanvasController* canvasController = KoToolManager::instance()->activeCanvasController();
232 KoSelection *selection = canvasController->canvas()->shapeManager()->selection();
233
234 if (isPage) {
235 // no shape is currently selected
236 if (!m_selectedShapes.isEmpty()) {
237 m_sectionView->clearSelection();
238 selection->deselectAll();
239 m_sectionView->setCurrentIndex(index);
240 m_selectedShapes.clear();
241 emit pageChanged(dynamic_cast<KoPAPageBase *>(shape));
242 }
243 else {
244 // There are more than one page selected
245 if (m_sectionView->selectionModel()->selectedIndexes().size() == 1) {
246 emit pageChanged(dynamic_cast<KoPAPageBase *>(shape));
247 }
248 }
249 }
250 else {
251 KoPAPageBase *newPageByShape = m_doc->pageByShape(shape);
252 // there is already shape(s) selected
253 if (!m_selectedShapes.isEmpty()) {
254 // if the newly selected shape is not in the same page as previously
255 // selected shape(s), then clear previous selection
256 KoPAPageBase *currentPage = m_doc->pageByShape(m_selectedShapes.first());
257 KoShapeLayer *layer = dynamic_cast<KoShapeLayer *>(shape);
258 if (currentPage != newPageByShape) {
259 m_sectionView->clearSelection();
260 selection->deselectAll();
261 m_sectionView->setCurrentIndex(index);
262 m_selectedShapes.clear();
263 emit pageChanged(newPageByShape);
264 if (layer) {
265 selection->setActiveLayer(layer);
266 }
267 else {
268 selection->select(shape);
269 shape->update();
270 }
271 }
272 else {
273 QList<KoPAPageBase*> selectedPages;
274 QList<KoShapeLayer*> selectedLayers;
275 QList<KoShape*> selectedShapes;
276
277 // separate selected layers and selected shapes
278 extractSelectedLayersAndShapes(selectedPages, selectedLayers, selectedShapes);
279
280 // XXX: Do stuff withthe selected pages!
281
282 foreach (KoShape* shape, selection->selectedShapes()) {
283 shape->update();
284 }
285 selection->deselectAll();
286 foreach (KoShape* shape, selectedShapes) {
287 if (shape) {
288 selection->select(shape);
289 shape->update();
290 }
291 }
292 // if we just selected a layer, check whether this layer is already active, if not
293 // then make it active
294 if (layer && selection->activeLayer() != layer && selectedLayers.count() <= 1) {
295 selection->setActiveLayer(layer);
296 }
297 }
298 }
299 // no shape is selected, meaning only page(s) is selected
300 else {
301 m_sectionView->clearSelection();
302 m_sectionView->setCurrentIndex(index);
303 selection->select(shape);
304 shape->update();
305 emit pageChanged(newPageByShape);
306 }
307 m_selectedShapes.append(shape);
308 }
309 }
310
addLayer()311 void KoPADocumentStructureDocker::addLayer()
312 {
313 bool ok = true;
314 QString name = QInputDialog::getText(this, i18n("New Layer"), i18n("Enter the name of the new layer:"),
315 QLineEdit::Normal, i18n("New layer"), &ok);
316 if (ok) {
317 KoShapeLayer* layer = new KoShapeLayer();
318 KoPACanvas * canvas = dynamic_cast<KoPACanvas *>(KoToolManager::instance()->activeCanvasController()->canvas());
319 if (canvas) {
320 layer->setParent(canvas->koPAView()->activePage());
321 layer->setName(name);
322 QList<KoShape*> layers(canvas->koPAView()->activePage()->shapes());
323 if (!layers.isEmpty()) {
324 std::sort(layers.begin(), layers.end(), KoShape::compareShapeZIndex);
325 layer->setZIndex(layers.last()->zIndex() + 1);
326 }
327 KUndo2Command *cmd = new KoShapeCreateCommand(m_doc, layer, 0);
328 cmd->setText(kundo2_i18n("Create Layer"));
329 m_doc->addCommand(cmd);
330 m_model->update();
331 }
332 }
333 }
334
deleteItem()335 void KoPADocumentStructureDocker::deleteItem()
336 {
337 QList<KoPAPageBase*> selectedPages;
338 QList<KoShapeLayer*> selectedLayers;
339 QList<KoShape*> selectedShapes;
340
341 // separate selected layers and selected shapes
342 extractSelectedLayersAndShapes(selectedPages, selectedLayers, selectedShapes);
343
344 KUndo2Command *cmd = 0;
345
346 if (selectedLayers.count()) {
347 if (m_doc->pages().count() > selectedPages.count()) {
348 QList<KoShape*> deleteShapes;
349 foreach(KoPAPageBase* page, selectedPages) {
350 deleteShapes += page->shapes();
351 deleteShapes.append(page);
352 }
353 cmd = new KoShapeDeleteCommand(m_doc, deleteShapes);
354 cmd->setText(kundo2_i18n("Delete Layer"));
355 }
356 else {
357 KMessageBox::error(0, i18n("Could not delete all layers. At least one layer is required."), i18n("Error deleting layers"));
358 }
359 }
360 else if (selectedShapes.count()) {
361 cmd = new KoShapeDeleteCommand(m_doc, selectedShapes);
362 }
363 else if (!selectedPages.isEmpty() && selectedPages.count() < m_doc->pages().count()) {
364 m_doc->removePages(selectedPages);
365 }
366
367 if (cmd) {
368 m_doc->addCommand(cmd);
369 m_model->update();
370 }
371 }
372
raiseItem()373 void KoPADocumentStructureDocker::raiseItem()
374 {
375 QList<KoPAPageBase*> selectedPages;
376 QList<KoShapeLayer*> selectedLayers;
377 QList<KoShape*> selectedShapes;
378
379 // separate selected layers and selected shapes
380 extractSelectedLayersAndShapes(selectedPages, selectedLayers, selectedShapes);
381
382 KUndo2Command *cmd = 0;
383
384 if (selectedLayers.count()) {
385 // // check if all layers could be raised
386 // foreach(KoShapeLayer* layer, selectedLayers)
387 // if (! m_document->canRaiseLayer(layer))
388 // return;
389
390 // cmd = new KoPALayerReorderCommand(m_document, selectedLayers, KoPALayerReorderCommand::RaiseLayer);
391 }
392 else if (selectedShapes.count()) {
393 cmd = KoShapeReorderCommand::createCommand(selectedShapes,
394 KoToolManager::instance()->activeCanvasController()->canvas()->shapeManager(),
395 KoShapeReorderCommand::RaiseShape);
396 }
397
398 if (cmd) {
399 m_doc->addCommand(cmd);
400 m_model->update();
401 }
402 }
403
lowerItem()404 void KoPADocumentStructureDocker::lowerItem()
405 {
406 QList<KoPAPageBase*> selectedPages;
407 QList<KoShapeLayer*> selectedLayers;
408 QList<KoShape*> selectedShapes;
409
410 // separate selected layers and selected shapes
411 extractSelectedLayersAndShapes(selectedPages, selectedLayers, selectedShapes);
412
413 KUndo2Command *cmd = 0;
414
415 if (selectedLayers.count()) {
416 // // check if all layers could be raised
417 // foreach(KoShapeLayer* layer, selectedLayers)
418 // if (! m_document->canLowerLayer(layer))
419 // return;
420
421 // cmd = new KoPALayerReorderCommand(m_document, selectedLayers, KoPALayerReorderCommand::LowerLayer);
422 }
423 else if (selectedShapes.count()) {
424 cmd = KoShapeReorderCommand::createCommand(selectedShapes,
425 KoToolManager::instance()->activeCanvasController()->canvas()->shapeManager(),
426 KoShapeReorderCommand::LowerShape);
427 }
428
429 if (cmd) {
430 m_doc->addCommand(cmd);
431 m_model->update();
432 }
433 }
434
extractSelectedLayersAndShapes(QList<KoPAPageBase * > & pages,QList<KoShapeLayer * > & layers,QList<KoShape * > & shapes)435 void KoPADocumentStructureDocker::extractSelectedLayersAndShapes(QList<KoPAPageBase*> &pages, QList<KoShapeLayer*> &layers, QList<KoShape*> &shapes)
436 {
437 pages.clear();
438 layers.clear();
439 shapes.clear();
440
441 QModelIndexList selectedItems = m_sectionView->selectionModel()->selectedIndexes();
442 if (selectedItems.count() == 0)
443 return;
444
445 // TODO tz: I don't know what is best:
446 // 1. only make it possible to select one type of object page, layer, shape
447 // 2. don't add shapes when we already have the page/layer/group in the selection
448 // separate selected layers and selected shapes
449 foreach(const QModelIndex & index, selectedItems) {
450 KoShape *shape = static_cast<KoShape*>(index.internalPointer());
451 KoPAPageBase * page = dynamic_cast<KoPAPageBase*>(shape);
452 if (page) {
453 pages.append(page);
454 }
455 else {
456 KoShapeLayer *layer = dynamic_cast<KoShapeLayer*>(shape);
457 if (layer)
458 layers.append(layer);
459 else if (! selectedItems.contains(index.parent()))
460 shapes.append(shape);
461 }
462 }
463 }
464
setCanvas(KoCanvasBase * canvas)465 void KoPADocumentStructureDocker::setCanvas(KoCanvasBase* canvas)
466 {
467 KoPACanvas * c = dynamic_cast<KoPACanvas*> (canvas);
468 if (c) {
469 m_doc = c->document();
470 m_model->setDocument(m_doc);
471 m_sectionView->setModel(m_model);
472 }
473 }
474
unsetCanvas()475 void KoPADocumentStructureDocker::unsetCanvas()
476 {
477 m_doc = 0;
478 m_model->setDocument(0);
479 m_sectionView->setModel(0);
480 }
481
setActivePage(KoPAPageBase * page)482 void KoPADocumentStructureDocker::setActivePage(KoPAPageBase *page)
483 {
484 if (m_doc) {
485 int row = m_doc->pageIndex(page);
486 QModelIndex index = m_model->index(row, 0);
487 if (index != m_sectionView->currentIndex()
488 && index != getRootIndex(m_sectionView->currentIndex())) {
489 m_sectionView->setCurrentIndex(index);
490 }
491 }
492 }
493
setMasterMode(bool master)494 void KoPADocumentStructureDocker::setMasterMode(bool master)
495 {
496 m_model->setMasterMode(master);
497 }
498
minimalView()499 void KoPADocumentStructureDocker::minimalView()
500 {
501 setViewMode(KoDocumentSectionView::MinimalMode);
502 m_itemsContextBar->disableContextBar();
503 }
504
detailedView()505 void KoPADocumentStructureDocker::detailedView()
506 {
507 setViewMode(KoDocumentSectionView::DetailedMode);
508 m_itemsContextBar->disableContextBar();
509 }
510
thumbnailView()511 void KoPADocumentStructureDocker::thumbnailView()
512 {
513 setViewMode(KoDocumentSectionView::ThumbnailMode);
514 m_itemsContextBar->enableContextBar();
515 }
516
setViewMode(KoDocumentSectionView::DisplayMode mode)517 void KoPADocumentStructureDocker::setViewMode(KoDocumentSectionView::DisplayMode mode)
518 {
519 bool expandable = (mode != KoDocumentSectionView::ThumbnailMode);
520
521 // if we switch to non-expandable mode (ThumbnailMode) and if current index
522 // is not a page, we need to select the corresponding page first, otherwise
523 // none of the page will be selected when we do collapse all
524 if (!expandable) {
525 QModelIndex currentIndex = m_sectionView->currentIndex();
526 QModelIndex rootIndex = getRootIndex(currentIndex);
527 if (currentIndex != rootIndex) {
528 m_sectionView->setCurrentIndex(rootIndex);
529 }
530 m_sectionView->collapseAll();
531 }
532
533 m_sectionView->setDisplayMode(mode);
534 m_sectionView->setItemsExpandable(expandable);
535 m_sectionView->setRootIsDecorated(expandable);
536 // m_sectionView->setSelectionMode(expandable ? QAbstractItemView::ExtendedSelection : QAbstractItemView::SingleSelection);
537
538 m_viewModeActions[mode]->setChecked (true);
539 }
540
getRootIndex(const QModelIndex & index) const541 QModelIndex KoPADocumentStructureDocker::getRootIndex(const QModelIndex &index) const
542 {
543 QModelIndex currentIndex;
544 QModelIndex parentIndex = index.parent();
545 if (!parentIndex.isValid()) {
546 return index;
547 }
548 while (parentIndex.isValid()) {
549 currentIndex = parentIndex;
550 parentIndex = currentIndex.parent();
551 }
552
553 return currentIndex;
554 }
555
viewModeFromString(const QString & mode)556 KoDocumentSectionView::DisplayMode KoPADocumentStructureDocker::viewModeFromString(const QString& mode)
557 {
558 if (mode == "Minimal")
559 return KoDocumentSectionView::MinimalMode;
560 else if (mode == "Detailed")
561 return KoDocumentSectionView::DetailedMode;
562 else if (mode == "Thumbnail")
563 return KoDocumentSectionView::ThumbnailMode;
564
565 return KoDocumentSectionView::DetailedMode;
566 }
567
viewModeToString(KoDocumentSectionView::DisplayMode mode)568 QString KoPADocumentStructureDocker::viewModeToString(KoDocumentSectionView::DisplayMode mode)
569 {
570 switch (mode)
571 {
572 case KoDocumentSectionView::MinimalMode:
573 return QString("Minimal");
574 break;
575 case KoDocumentSectionView::DetailedMode:
576 return QString("Detailed");
577 break;
578 case KoDocumentSectionView::ThumbnailMode:
579 return QString("Thumbnail");
580 break;
581 }
582
583 return QString();
584 }
585
itemSelected(const QItemSelection & selected,const QItemSelection & deselected)586 void KoPADocumentStructureDocker::itemSelected(const QItemSelection& selected, const QItemSelection& deselected)
587 {
588 Q_UNUSED(deselected);
589
590 if (selected.indexes().isEmpty()) {
591 m_buttonGroup->button(Button_Raise)->setEnabled(false);
592 m_buttonGroup->button(Button_Lower)->setEnabled(false);
593 m_addLayerAction->setEnabled(false);
594 }
595 else {
596 m_buttonGroup->button(Button_Raise)->setEnabled(true);
597 m_buttonGroup->button(Button_Lower)->setEnabled(true);
598 m_addLayerAction->setEnabled(true);
599 }
600
601 if (!m_sectionView->selectionModel()->selectedIndexes().empty() &&
602 m_sectionView->selectionModel()->selectedIndexes().count() < m_doc->pages().count()) {
603 m_buttonGroup->button(Button_Delete)->setEnabled(true);
604 }
605 else {
606 m_buttonGroup->button(Button_Delete)->setEnabled(false);
607 }
608 }
609
addPage()610 void KoPADocumentStructureDocker::addPage()
611 {
612 KoPACanvas * canvas = dynamic_cast<KoPACanvas *>(KoToolManager::instance()->activeCanvasController()->canvas());
613 if (canvas) {
614 canvas->koPAView()->insertPage();
615 }
616 }
617
contextMenuEvent(QContextMenuEvent * event)618 void KoPADocumentStructureDocker::contextMenuEvent(QContextMenuEvent* event)
619 {
620 QMenu menu(this);
621
622 // Not connected yet
623 if (m_doc->pageType() == KoPageApp::Slide) {
624 menu.addAction(koIcon("document-new"), i18n("Add a new slide"), this, SLOT(addPage()));
625 }
626 else {
627 menu.addAction(koIcon("document-new"), i18n("Add a new page"), this, SLOT(addPage()));
628 }
629 menu.addAction(koIcon("edit-delete"), i18n("Delete selected objects"), this, SLOT(deleteItem()));
630 menu.addSeparator();
631 menu.addAction(koIcon("edit-cut"), i18n("Cut"), this, SLOT(editCut()));
632 menu.addAction(koIcon("edit-copy"), i18n("Copy"), this, SLOT(editCopy()));
633 menu.addAction(koIcon("edit-paste"), i18n("Paste"), this, SLOT(editPaste()));
634
635 menu.exec(event->globalPos());
636 }
637
editCut()638 void KoPADocumentStructureDocker::editCut()
639 {
640 editCopy();
641 deleteItem();
642 }
643
editCopy()644 void KoPADocumentStructureDocker::editCopy()
645 {
646 QList<KoPAPageBase*> pages;
647 QList<KoShapeLayer*> layers;
648 QList<KoShape*> shapes;
649
650 // separate selected layers and selected shapes
651 extractSelectedLayersAndShapes(pages, layers, shapes);
652
653 foreach (KoShape* shape, layers) {
654 // Add layers to shapes
655 shapes.append(shape);
656 }
657
658 if (!shapes.empty()) {
659 // Copy Shapes or Layers
660 KoShapeOdfSaveHelper saveHelper(shapes);
661 KoDrag drag;
662 drag.setOdf(KoOdf::mimeType(KoOdf::Text), saveHelper);
663 drag.addToClipboard();
664 return;
665 }
666
667 if (!pages.empty()) {
668 // Copy Pages
669 KoPAOdfPageSaveHelper saveHelper(m_doc, pages);
670 KoDrag drag;
671 drag.setOdf(KoOdf::mimeType(m_doc->documentType()), saveHelper);
672 drag.addToClipboard();
673 }
674 }
675
editPaste()676 void KoPADocumentStructureDocker::editPaste()
677 {
678 const QMimeData * data = QApplication::clipboard()->mimeData();
679
680 if (data->hasFormat(KoOdf::mimeType(KoOdf::Text))) {
681 // Paste Shapes or Layers
682 KoCanvasBase* canvas = KoToolManager::instance()->activeCanvasController()->canvas();
683 KoShapeManager * shapeManager = canvas->shapeManager();
684 KoShapePaste paste(canvas, shapeManager->selection()->activeLayer());
685 paste.paste(KoOdf::Text, data);
686
687 }
688 else {
689 // Paste Pages
690 KoPACanvas * canvas = static_cast<KoPACanvas *>(KoToolManager::instance()->activeCanvasController()->canvas());
691 canvas->koPAView()->pagePaste();
692 }
693 }
694
selectPages(int start,int count)695 void KoPADocumentStructureDocker::selectPages(int start, int count)
696 {
697 if ((start < 0) || (count < 1)) {
698 return;
699 }
700 emit pageChanged(m_doc->pageByIndex(start, false));
701 m_sectionView->clearSelection();
702 for (int i = start; i < (start + count); i++) {
703 QModelIndex index = m_model->index(i, 0, QModelIndex());
704 if (index.isValid()) {
705 m_sectionView->selectionModel()->select(index, QItemSelectionModel::Select);
706 }
707 }
708 }
709
710 // kate: replace-tabs on; space-indent on; indent-width 4; mixedindent off; indent-mode cstyle;
711