From af6dc9c691c72b2bf3e48f924d2e05f047417724 Mon Sep 17 00:00:00 2001 From: Claudio Valerio Date: Tue, 4 Mar 2014 10:18:15 +0100 Subject: [PATCH] merge --- resources/etc/OpenBoard.css | 760 +++++++++++++------------- src/document/UBDocumentController.cpp | 296 +++++----- src/document/UBDocumentController.h | 10 + src/document/UBDocumentProxy.cpp | 2 +- src/gui/UBDocumentTreeWidget.cpp | 141 ++++- src/gui/UBDocumentTreeWidget.h | 12 +- 6 files changed, 695 insertions(+), 526 deletions(-) diff --git a/resources/etc/OpenBoard.css b/resources/etc/OpenBoard.css index 935c0287..891f767e 100644 --- a/resources/etc/OpenBoard.css +++ b/resources/etc/OpenBoard.css @@ -1,382 +1,388 @@ -QWidget:enabled -{ - color: #3F3F3F; +QWidget:enabled +{ + color: #3F3F3F; } QWidget:disabled { color: #777777; -} - -QTextEdit, -QLineEdit, -QComboBox#DockPaletteWidgetComboBox QAbstractItemView -{ - selection-background-color: lightgreen; - selection-color: black; -} -QProgressBar:horizontal { - border: 1px solid gray; - border-radius: 3px; - background: white; - padding: 1px; -} -QProgressBar::chunk:horizontal { - /*background: qlineargradient(x1: 0, y1: 0.5, x2: 1, y2: 0.5, stop: 0 green, stop: 1 lightgreen);*/ - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4); -} - -QMainWindow -{ - background-color: #F1F1F1; -} - -QDialog -{ - background-color: #dddddd; -} - -QMenu -{ - border: none; - font-size: 12px; -} - -QMenu::item -{ - background-color: #b3b3b3; -} - -QMenu::item:selected -{ - background-color: #9f9f9f; -} - -QMenu::separator -{ - background-color: #b3b3b3; - border: 1px dotted #888888; -} - -QToolBar -{ - spacing: 0px; - background-color: #b3b3b3; - border: none; - border-bottom: 1px solid #888888; -} - -QToolBar::handle -{ - margin: 2px; - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #d3d3d3, stop: 1 #c4c4c4); -} - -QToolBar::separator -{ - border: 1px dotted #888888; border-left: none; margin-left: 5px; margin-right: 5px; width: 1px; -} - -QToolBar QToolButton -{ - - margin: 4px; - margin-left: 0px; - margin-right: 0px; - padding: 0px; - border: none; - height: 58px; -} - -QToolBar QToolButton:pressed -{ - margin: 4px; - margin-left: 0px; - margin-right: 0px; - padding: 0px; - border: none; - height: 58px; - - background: qradialgradient(cx:0.5, cy:0.5, radius: 0.5, - fx:0.5, fy:0.5, stop: 0 #d3d3d3, stop: 1 #b3b3b3); -} - -QDialog QToolButton:pressed -{ - background: qradialgradient(cx:0.5, cy:0.5, radius: 0.5, - fx:0.5, fy:0.5, stop: 0 #ffffff, stop: 1 #dddddd); -} - -QToolButton#ubButtonGroupLeft -{ - background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #d3d3d3, stop: 1 #c4c4c4); - margin-top: 1px; - margin-right: 0px; - padding: 5px; - - border: 1px solid #444444; - border-right: none; - border-top-left-radius : 3px; - border-bottom-left-radius : 3px; - height: 14px; -} - -QToolButton#ubButtonGroupCenter -{ - background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #d3d3d3, stop: 1 #c4c4c4); - margin-top: 1px; - margin-right: 0px; - margin-left: 0px; - padding: 5px; - - border: 1px solid #444444; - border-right: none; - border-left: none; - height: 14px; -} - -QToolButton#ubButtonGroupRight -{ - background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #d3d3d3, stop: 1 #c4c4c4); - margin-top: 1px; - margin-left: 0px; - padding: 5px; - - border: 1px solid #444444; - border-left: none; - border-top-right-radius : 3px; - border-bottom-right-radius : 3px; - height: 14px; -} - -QToolButton#ubButtonGroupLeft:checked, -QToolButton#ubButtonGroupCenter:checked, -QToolButton#ubButtonGroupRight:checked -{ - background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #c3c3c3, stop: 1 #b4b4b4); -} - -QToolButton#ubButtonGroupLeft:checked -{ - border-right: 1px solid #444444; - padding-right: 4px; -} - -QToolButton#ubButtonGroupCenter:checked -{ - border-left: 1px solid #444444; - border-right: 1px solid #444444; - padding-right: 4px; - padding-left: 4px; -} - -QToolButton#ubButtonGroupRight:checked -{ - border-left: 1px solid #444444; - padding-left: 4px; -} - -QToolButton#ubButtonMenu -{ - margin-right: 2px; - padding-right: 12px; -} - -QToolButton#ubButtonMenu:pressed, -QToolButton#ubButtonMenu:checked -{ - background-color: #b3b3b3; -} - -QToolButton#ubActionPaletteButton -{ - margin: 0px; -} - -QFrame#newDocumentFolderFrame, -QFrame#newDocumentFrame, -QFrame#newFolderFrame -{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e6eaf0, stop: 1 #dbe0e8); - margin: 0px; - padding: 0px; - border: none; -} - -QFrame#topLeftFrame, -QFrame#imageTopLeftFrame, -QFrame#interactiveTopLeftFrame, -QFrame#videoTopLeftFrame, -QFrame#toolTopLeftFrame -{ - border: none; - border-right: 1px solid #888888; -} - -QWidget#topRightFrame -{ - background-color: #d3d3d3; -} - -QFrame#toolFrame -{ - border-top: 1px solid #888888; -} - -QTreeView -{ - background-color: rgb(209, 215, 226); -} - -QTreeView::item:selected:active -{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #AAB7C4, stop: 1 #7e8eA0); - border: none; -} - -QTreeView::item -{ - padding-top: 1.5 px; - padding-bottom: 1.5 px; -} - -QTreeView::item:selected, -QTreeView::branch:selected -{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #AAB7C4, stop: 1 #7e8eA0); - border: none; -} - -QTreeView::branch:has-siblings:!adjoins-item, -QTreeView::branch:!has-children:!has-siblings:adjoins-item, -QTreeView::branch:has-siblings:adjoins-item -{ - border-image: none; - image: none; -} - -QTreeView::branch:has-children:!has-siblings:closed, -QTreeView::branch:closed:has-children:has-siblings -{ - border-image: none; - image: url(:/style/treeview-branch-closed.png); -} - -QTreeView::branch:open:has-children:!has-siblings, -QTreeView::branch:open:has-children:has-siblings -{ - border-image: none; - image: url(:/style/treeview-branch-open.png); -} - -QSlider::groove:horizontal -{ - border: 1px solid #999999; - height: 2px; - background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4); - margin: 2px 0; -} - -QSlider::handle:horizontal -{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #aaaaaa, stop: 1 #b8b8b8); - border: 1px solid #5c5c5c; - - width: 18px; - margin: -2px 0; - border-radius: 6px; -} - -QTabWidget::pane -{ - border: 1px solid #888888; - margin-top: -2px; -} - -QTabWidget::pane#libraryTabWidget -{ - border: none; - border-top: 1px solid #888888; -} - -QTabWidget::tab-bar -{ - alignment: center; -} - -QTabWidget::tab-bar#ubWebBrowserTabWidget -{ - background: #dddddd; - alignment: left; -} - -QTabBar::tab -{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #d3d3d3, stop: 1 #c4c4c4); - - border: 1px solid #888888; - - border-bottom: none; - - border-top-left-radius: 3px; - border-top-right-radius: 3px; - - min-width: 15ex; - margin: 2px; - margin-top: 6px; - margin-bottom: 2px; - padding: 4px; - - height: 14px; -} - -QTabBar::tab:first -{ - border-left: 1px solid #888888; -} - -QTabBar::tab:last -{ - border-right: 1px solid #888888; -} - -QTabBar::tab:selected -{ - border-right: 1px solid #888888; - border-left: 1px solid #888888; - border-bottom: none; -} - -QTabBar::tab:first:selected -{ - border-right: 1px solid #888888; -} - -QTabBar::tab:last:selected -{ - border-left: 1px solid #888888; -} - -QTabBar::tab:selected -{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #aaaaaa, stop: 1 #b8b8b8); -} - -QTabBar::tab#ubWebBrowserTabBar -{ - background: #dddddd; - min-width: 150px; -} - -QTabBar::tab:selected#ubWebBrowserTabBar -{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #b3b3b3, stop: 1 #dddddd); -} - -QLineEdit#ubWebBrowserLineEdit -{ - border: 1px solid #888888; - border-radius: 3px; - padding: 2 2px; - background: white; -} +} + +QTextEdit, +QLineEdit, +QComboBox#DockPaletteWidgetComboBox QAbstractItemView +{ + selection-background-color: lightgreen; + selection-color: black; +} +QProgressBar:horizontal { + border: 1px solid gray; + border-radius: 3px; + background: white; + padding: 1px; +} +QProgressBar::chunk:horizontal { + /*background: qlineargradient(x1: 0, y1: 0.5, x2: 1, y2: 0.5, stop: 0 green, stop: 1 lightgreen);*/ + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4); +} + +QMainWindow +{ + background-color: #F1F1F1; +} + +QDialog +{ + background-color: #dddddd; +} + +QMenu +{ + border: none; + font-size: 12px; +} + +QMenu::item +{ + background-color: #b3b3b3; +} + +QMenu::item:selected +{ + background-color: #9f9f9f; +} + +QMenu::separator +{ + background-color: #b3b3b3; + border: 1px dotted #888888; +} + +QToolBar +{ + spacing: 0px; + background-color: #b3b3b3; + border: none; + border-bottom: 1px solid #888888; +} + +QToolBar::handle +{ + margin: 2px; + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #d3d3d3, stop: 1 #c4c4c4); +} + +QToolBar::separator +{ + border: 1px dotted #888888; border-left: none; margin-left: 5px; margin-right: 5px; width: 1px; +} + +QToolBar QToolButton +{ + + margin: 4px; + margin-left: 0px; + margin-right: 0px; + padding: 0px; + border: none; + height: 58px; +} + +QToolBar QToolButton:pressed +{ + margin: 4px; + margin-left: 0px; + margin-right: 0px; + padding: 0px; + border: none; + height: 58px; + + background: qradialgradient(cx:0.5, cy:0.5, radius: 0.5, + fx:0.5, fy:0.5, stop: 0 #d3d3d3, stop: 1 #b3b3b3); +} + +QDialog QToolButton:pressed +{ + background: qradialgradient(cx:0.5, cy:0.5, radius: 0.5, + fx:0.5, fy:0.5, stop: 0 #ffffff, stop: 1 #dddddd); +} + +QToolButton#ubButtonGroupLeft +{ + background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #d3d3d3, stop: 1 #c4c4c4); + margin-top: 1px; + margin-right: 0px; + padding: 5px; + + border: 1px solid #444444; + border-right: none; + border-top-left-radius : 3px; + border-bottom-left-radius : 3px; + height: 14px; +} + +QToolButton#ubButtonGroupCenter +{ + background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #d3d3d3, stop: 1 #c4c4c4); + margin-top: 1px; + margin-right: 0px; + margin-left: 0px; + padding: 5px; + + border: 1px solid #444444; + border-right: none; + border-left: none; + height: 14px; +} + +QToolButton#ubButtonGroupRight +{ + background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #d3d3d3, stop: 1 #c4c4c4); + margin-top: 1px; + margin-left: 0px; + padding: 5px; + + border: 1px solid #444444; + border-left: none; + border-top-right-radius : 3px; + border-bottom-right-radius : 3px; + height: 14px; +} + +QToolButton#ubButtonGroupLeft:checked, +QToolButton#ubButtonGroupCenter:checked, +QToolButton#ubButtonGroupRight:checked +{ + background: qlineargradient(x1: 0, y1: 0.49, x2: 0, y2: 0.5, stop: 0 #c3c3c3, stop: 1 #b4b4b4); +} + +QToolButton#ubButtonGroupLeft:checked +{ + border-right: 1px solid #444444; + padding-right: 4px; +} + +QToolButton#ubButtonGroupCenter:checked +{ + border-left: 1px solid #444444; + border-right: 1px solid #444444; + padding-right: 4px; + padding-left: 4px; +} + +QToolButton#ubButtonGroupRight:checked +{ + border-left: 1px solid #444444; + padding-left: 4px; +} + +QToolButton#ubButtonMenu +{ + margin-right: 2px; + padding-right: 12px; +} + +QToolButton#ubButtonMenu:pressed, +QToolButton#ubButtonMenu:checked +{ + background-color: #b3b3b3; +} + +QToolButton#ubActionPaletteButton +{ + margin: 0px; +} + +QFrame#newDocumentFolderFrame, +QFrame#newDocumentFrame, +QFrame#newFolderFrame +{ + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e6eaf0, stop: 1 #dbe0e8); + margin: 0px; + padding: 0px; + border: none; +} + +QFrame#topLeftFrame, +QFrame#imageTopLeftFrame, +QFrame#interactiveTopLeftFrame, +QFrame#videoTopLeftFrame, +QFrame#toolTopLeftFrame +{ + border: none; + border-right: 1px solid #888888; +} + +QWidget#topRightFrame +{ + background-color: #d3d3d3; +} + +QFrame#toolFrame +{ + border-top: 1px solid #888888; +} + +QTreeView +{ + background-color: rgb(209, 215, 226); +} + +QTreeView::item:selected:active +{ + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #AAB7C4, stop: 1 #7e8eA0); + border: none; +} + +QTreeView::item +{ + padding-top: 1.5 px; + padding-bottom: 1.5 px; +} + +QTreeView::item:selected, +QTreeView::branch:selected +{ + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #AAB7C4, stop: 1 #7e8eA0); + border: none; +} + +QTreeView::branch:has-siblings:!adjoins-item, +QTreeView::branch:!has-children:!has-siblings:adjoins-item, +QTreeView::branch:has-siblings:adjoins-item +{ + border-image: none; + image: none; +} + +QTreeView::branch:has-children:!has-siblings:closed, +QTreeView::branch:closed:has-children:has-siblings +{ + border-image: none; + image: url(:/style/treeview-branch-closed.png); +} + +QTreeView::branch:open:has-children:!has-siblings, +QTreeView::branch:open:has-children:has-siblings +{ + border-image: none; + image: url(:/style/treeview-branch-open.png); +} + +QSlider::groove:horizontal +{ + border: 1px solid #999999; + height: 2px; + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4); + margin: 2px 0; +} + +QSlider::handle:horizontal +{ + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #aaaaaa, stop: 1 #b8b8b8); + border: 1px solid #5c5c5c; + + width: 18px; + margin: -2px 0; + border-radius: 6px; +} + +QTabWidget::pane +{ + border: 1px solid #888888; + margin-top: -2px; +} + +QTabWidget::pane#libraryTabWidget +{ + border: none; + border-top: 1px solid #888888; +} + +QTabWidget::tab-bar +{ + alignment: center; +} + +QTabWidget::tab-bar#ubWebBrowserTabWidget +{ + background: #dddddd; + alignment: left; +} + +QTabBar::tab +{ + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #d3d3d3, stop: 1 #c4c4c4); + + border: 1px solid #888888; + + border-bottom: none; + + border-top-left-radius: 3px; + border-top-right-radius: 3px; + + min-width: 15ex; + margin: 2px; + margin-top: 6px; + margin-bottom: 2px; + padding: 4px; + + height: 14px; +} + +QTabBar::tab:first +{ + border-left: 1px solid #888888; +} + +QTabBar::tab:last +{ + border-right: 1px solid #888888; +} + +QTabBar::tab:selected +{ + border-right: 1px solid #888888; + border-left: 1px solid #888888; + border-bottom: none; +} + +QTabBar::tab:first:selected +{ + border-right: 1px solid #888888; +} + +QTabBar::tab:last:selected +{ + border-left: 1px solid #888888; +} + +QTabBar::tab:selected +{ + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #aaaaaa, stop: 1 #b8b8b8); +} + +QTabBar::tab#ubWebBrowserTabBar +{ + background: #dddddd; + min-width: 150px; +} + +QTabBar::tab:selected#ubWebBrowserTabBar +{ + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #b3b3b3, stop: 1 #dddddd); +} + +QLineEdit#ubWebBrowserLineEdit +{ + border: 1px solid #888888; + border-radius: 3px; + padding: 2 2px; + background: white; +} + +QSplitter +{ + background-color: #b3b3b3; + width : 15px; + diff --git a/src/document/UBDocumentController.cpp b/src/document/UBDocumentController.cpp index decc2811..ac8ee046 100644 --- a/src/document/UBDocumentController.cpp +++ b/src/document/UBDocumentController.cpp @@ -103,7 +103,9 @@ void UBDocumentController::createNewDocument() if (group) { - UBDocumentProxy *document = UBPersistenceManager::persistenceManager()->createDocument(group->groupName()); + QString path = group->buildEntirePath(); + + UBDocumentProxy *document = UBPersistenceManager::persistenceManager()->createDocument(path); selectDocument(document); } @@ -201,7 +203,19 @@ void UBDocumentController::createNewDocumentGroup() int trashIndex = mDocumentUI->documentTreeWidget->indexOfTopLevelItem(mTrashTi); - mDocumentUI->documentTreeWidget->insertTopLevelItem(trashIndex, docGroupItem); + UBDocumentGroupTreeItem* selected = selectedDocumentGroupTreeItem(); + + QString parentGroupName(""); + if(selected->groupName().contains(mDefaultDocumentGroupName)) + mDocumentUI->documentTreeWidget->insertTopLevelItem(trashIndex, docGroupItem); + else + selected->addChild(docGroupItem); + + parentGroupName = docGroupItem->buildEntirePath(); + + mMapOfPaths.insert(parentGroupName,docGroupItem); + + mDocumentUI->documentTreeWidget->setCurrentItem(docGroupItem); mDocumentUI->documentTreeWidget->expandItem(docGroupItem); } @@ -293,8 +307,7 @@ void UBDocumentController::setupViews() mDocumentUI->documentZoomSlider->setValue(thumbWidth); mDocumentUI->thumbnailWidget->setThumbnailWidth(thumbWidth); - connect(mDocumentUI->documentZoomSlider, SIGNAL(valueChanged(int)), this, - SLOT(documentZoomSliderValueChanged(int))); + connect(mDocumentUI->documentZoomSlider, SIGNAL(valueChanged(int)), this, SLOT(documentZoomSliderValueChanged(int))); connect(mMainWindow->actionOpen, SIGNAL(triggered()), this, SLOT(openSelectedItem())); connect(mMainWindow->actionNewFolder, SIGNAL(triggered()), this, SLOT(createNewDocumentGroup())); @@ -525,9 +538,9 @@ void UBDocumentController::duplicateSelectedItem() if (source && group) { - QString docName = source->metaData(UBSettings::documentName).toString(); + QString docName = source->metaData(UBSettings::documentName).toString(); - showMessage(tr("Duplicating Document %1").arg(docName), true); + showMessage(tr("Duplicating Document %1").arg(docName), true); UBDocumentProxy* duplicatedDoc = UBPersistenceManager::persistenceManager()->duplicateDocument(source); duplicatedDoc->setMetaData(UBSettings::documentUpdatedAt, UBStringUtils::toUtcIsoDateTime(QDateTime::currentDateTime())); @@ -612,6 +625,38 @@ void UBDocumentController::moveDocumentToTrash(UBDocumentGroupTreeItem* groupTi, proxyTi->setFlags(proxyTi->flags() ^ Qt::ItemIsEditable); } + +QList UBDocumentController::getProxies(QTreeWidgetItem* groupItem) +{ + QList result; + + for(int i = 0; i < groupItem->childCount(); i += 1){ + UBDocumentProxyTreeItem* docProxy = dynamic_cast(groupItem->child(i)); + if(docProxy) + result.append(docProxy); + else + result << getProxies(groupItem->child(i)); + } + + return result; +} + + +QList UBDocumentController::getGroupTreeItem(QTreeWidgetItem* groupItem) +{ + QList result; + + for(int i = 0; i < groupItem->childCount(); i += 1){ + UBDocumentGroupTreeItem* group = dynamic_cast(groupItem->child(i)); + if(group) + result.append(group); + else + result << getGroupTreeItem(groupItem->child(i)); + } + + return result; +} + void UBDocumentController::moveFolderToTrash(UBDocumentGroupTreeItem* groupTi) { bool changeCurrentDocument = false; @@ -625,14 +670,9 @@ void UBDocumentController::moveFolderToTrash(UBDocumentGroupTreeItem* groupTi) } } - QList toBeDeleted; - for (int i = 0; i < groupTi->childCount(); i++) - { - UBDocumentProxyTreeItem* proxyTi = dynamic_cast(groupTi->child(i)); - if (proxyTi && proxyTi->proxy()) - toBeDeleted << proxyTi; - } + + QList toBeDeleted = getProxies(groupTi); for (int i = 0; i < toBeDeleted.count(); i++) { @@ -644,21 +684,38 @@ void UBDocumentController::moveFolderToTrash(UBDocumentGroupTreeItem* groupTi) proxyTi->proxy()->setMetaData(UBSettings::documentGroupName, UBSettings::trashedDocumentGroupNamePrefix + oldGroupName); UBPersistenceManager::persistenceManager()->persistDocumentMetadata(proxyTi->proxy()); - groupTi->removeChild(proxyTi); + UBDocumentGroupTreeItem* parentDirectory = dynamic_cast(mMapOfPaths.value(oldGroupName)); + parentDirectory->removeChild(proxyTi); mTrashTi->addChild(proxyTi); proxyTi->setFlags(proxyTi->flags() ^ Qt::ItemIsEditable); showMessage(QString("%1 deleted").arg(groupTi->groupName())); } + + QList dirToDelete = getGroupTreeItem(groupTi); + for(int i = dirToDelete.count() - 1; i >= 0 ; i -= 1){ + UBDocumentGroupTreeItem* parent = dynamic_cast(dirToDelete.at(i)->parent()); + if(parent){ + mMapOfPaths.remove(dirToDelete.at(i)->buildEntirePath()); + parent->removeChild(dirToDelete.at(i)); + } + } + + // dont remove default group if (!groupTi->isDefaultFolder()) { int index = mDocumentUI->documentTreeWidget->indexOfTopLevelItem(groupTi); if (index >= 0) - { mDocumentUI->documentTreeWidget->takeTopLevelItem(index); + else { + UBDocumentGroupTreeItem* parent = dynamic_cast(groupTi->parent()); + if(parent){ + mMapOfPaths.remove(groupTi->buildEntirePath()); + parent->removeChild(groupTi); + } } } @@ -809,96 +866,56 @@ void UBDocumentController::documentZoomSliderValueChanged (int value) } +UBDocumentGroupTreeItem* UBDocumentController::getCommonGroupItem(QString &path) +{ + QList paths = mMapOfPaths.keys(); + + if(paths.count() == 0) + return NULL; + + QString commonPath = path; + do{ + if(paths.contains(commonPath)) + return mMapOfPaths.value(commonPath); + else{ + int lastSeparatorIndex = commonPath.lastIndexOf("/"); + if(lastSeparatorIndex>0) + commonPath = commonPath.left(lastSeparatorIndex); + else + commonPath = ""; + } + }while(commonPath.length() > 0); + + return NULL; +} + void UBDocumentController::loadDocumentProxies() { QList > proxies = UBPersistenceManager::persistenceManager()->documentProxies; - QStringList emptyGroupNames = UBSettings::settings()->value("Document/EmptyGroupNames", QStringList()).toStringList(); - mDocumentUI->documentTreeWidget->clear(); - QMap groupNamesMap; - - UBDocumentGroupTreeItem* emptyGroupNameTi = 0; + UBDocumentGroupTreeItem* emptyGroupNameTi = new UBDocumentGroupTreeItem(0, false); + emptyGroupNameTi->setGroupName(mDefaultDocumentGroupName); + emptyGroupNameTi->setIcon(0, QIcon(":/images/toolbar/documents.png")); + mMapOfPaths.insert(mDefaultDocumentGroupName,emptyGroupNameTi); mTrashTi = new UBDocumentGroupTreeItem(0, false); // deleted by the tree widget mTrashTi->setGroupName(mDocumentTrashGroupName); mTrashTi->setIcon(0, QIcon(":/images/trash.png")); + mMapOfPaths.insert(mDocumentTrashGroupName,mTrashTi); + + mDocumentUI->documentTreeWidget->addTopLevelItem(emptyGroupNameTi); + mDocumentUI->documentTreeWidget->addTopLevelItem(mTrashTi); + foreach (QPointer proxy, proxies) { if (proxy) { - QString docGroup = proxy->metaData(UBSettings::documentGroupName).toString(); - - - bool isEmptyGroupName = false; - bool isInTrash = false; - - if (docGroup.isEmpty()) // #see https://trac.assembla.com/uniboard/ticket/426 - { - docGroup = mDefaultDocumentGroupName; - isEmptyGroupName = true; - } - else if (docGroup.startsWith(UBSettings::trashedDocumentGroupNamePrefix)) - { - isInTrash = true; - } - - QString docName = proxy->metaData(UBSettings::documentName).toString(); - - if (emptyGroupNames.contains(docGroup)) - emptyGroupNames.removeAll(docGroup); - - if (!groupNamesMap.contains(docGroup) && !isInTrash) - { - UBDocumentGroupTreeItem* docGroupItem = new UBDocumentGroupTreeItem(0, !isEmptyGroupName); // deleted by the tree widget - groupNamesMap.insert(docGroup, docGroupItem); - docGroupItem->setGroupName(docGroup); - - if (isEmptyGroupName) - emptyGroupNameTi = docGroupItem; - } - - UBDocumentGroupTreeItem* docGroupItem; - if (isInTrash) - docGroupItem = mTrashTi; - else - docGroupItem = groupNamesMap.value(docGroup); - - QTreeWidgetItem* docItem = new UBDocumentProxyTreeItem(docGroupItem, proxy, !isInTrash); - docItem->setText(0, docName); - - if (mBoardController->selectedDocument() == proxy) - { - mDocumentUI->documentTreeWidget->expandItem(docGroupItem); - mDocumentUI->documentTreeWidget->setCurrentItem(docGroupItem); - } + addDocumentInTree(proxy); } } - - foreach (const QString emptyGroupName, emptyGroupNames) - { - UBDocumentGroupTreeItem* docGroupItem = new UBDocumentGroupTreeItem(0); // deleted by the tree widget - groupNamesMap.insert(emptyGroupName, docGroupItem); - docGroupItem->setGroupName(emptyGroupName); - } - - QList groupNamesList = groupNamesMap.keys(); - qSort(groupNamesList); - - foreach (const QString groupName, groupNamesList) - { - UBDocumentGroupTreeItem* ti = groupNamesMap.value(groupName); - - if (ti != emptyGroupNameTi) - mDocumentUI->documentTreeWidget->addTopLevelItem(ti); - } - - if (emptyGroupNameTi) - mDocumentUI->documentTreeWidget->addTopLevelItem(emptyGroupNameTi); - - mDocumentUI->documentTreeWidget->addTopLevelItem(mTrashTi); } @@ -912,12 +929,27 @@ void UBDocumentController::itemClicked(QTreeWidgetItem * item, int column ) } +void UBDocumentController::treeGroupItemRenamed(QString& oldPath,QString& newPath) +{ + if(oldPath.isEmpty() || newPath.isEmpty()) + return; + + QList keys = mMapOfPaths.keys(); + for(int i = 0; i < keys.count(); i += 1){ + QString key = keys.at(i); + if(key.startsWith(oldPath)){ + UBDocumentGroupTreeItem* value = mMapOfPaths.take(key); + key = key.remove(0,oldPath.size()); + mMapOfPaths.insert(key.prepend(newPath),value); + } + } +} + void UBDocumentController::itemChanged(QTreeWidgetItem * item, int column) { UBDocumentProxyTreeItem* proxyItem = dynamic_cast(item); - disconnect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)) - , this, SLOT(updateDocumentInTree(UBDocumentProxy*))); + disconnect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)) , this, SLOT(updateDocumentInTree(UBDocumentProxy*))); if (proxyItem) { @@ -939,7 +971,6 @@ void UBDocumentController::itemChanged(QTreeWidgetItem * item, int column) if (childItem) { - QString groupName; if (0 != (item->flags() & Qt::ItemIsEditable)) { childItem->proxy()->setMetaData(UBSettings::documentGroupName, item->text(column)); @@ -950,8 +981,7 @@ void UBDocumentController::itemChanged(QTreeWidgetItem * item, int column) } } - connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)), - this, SLOT(updateDocumentInTree(UBDocumentProxy*))); + connect(UBPersistenceManager::persistenceManager(), SIGNAL(documentMetadataChanged(UBDocumentProxy*)), this, SLOT(updateDocumentInTree(UBDocumentProxy*))); } @@ -1341,42 +1371,51 @@ void UBDocumentController::addToDocument() } +UBDocumentGroupTreeItem* UBDocumentController::getParentTreeItem(QString& documentGroup) +{ + QString pathNotYetCreated = documentGroup; + UBDocumentGroupTreeItem* result = getCommonGroupItem(documentGroup); + if(result) + pathNotYetCreated = pathNotYetCreated.remove(0,result->buildEntirePath().size()); + + if(pathNotYetCreated.startsWith("/")) pathNotYetCreated = pathNotYetCreated.remove(0,1); + QString completePath = result ? result->groupName() + "/" : ""; + + QStringList folders = pathNotYetCreated.split("/"); + for(int i = 0; i < folders.count(); i += 1 ){ + if(!folders.at(i).isEmpty()){ + completePath = completePath + folders.at(i); + UBDocumentGroupTreeItem* newTreeItem = new UBDocumentGroupTreeItem(result, true); + newTreeItem->setGroupName(folders.at(i)); + if(completePath.indexOf("/") == -1) + mDocumentUI->documentTreeWidget->insertTopLevelItem(0,newTreeItem); + mMapOfPaths.insert(completePath,newTreeItem); + result = newTreeItem; + completePath += "/"; + } + } + + return result; +} + void UBDocumentController::addDocumentInTree(UBDocumentProxy* pDocument) { QString documentName = pDocument->name(); QString documentGroup = pDocument->groupName(); + if (documentGroup.isEmpty()) - { documentGroup = mDefaultDocumentGroupName; - } - UBDocumentGroupTreeItem* group = 0; + + UBDocumentGroupTreeItem* group = NULL; + if (documentGroup.startsWith(UBSettings::trashedDocumentGroupNamePrefix)) - { group = mTrashTi; - } else - { - for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) - { - QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); - UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - if (groupItem->groupName() == documentGroup) - { - group = groupItem; - break; - } - } - } - - if (group == 0) - { - group = new UBDocumentGroupTreeItem(0); // deleted by the tree widget - group->setGroupName(documentGroup); - mDocumentUI->documentTreeWidget->addTopLevelItem(group); - } + group = getParentTreeItem(documentGroup); UBDocumentProxyTreeItem *ti = new UBDocumentProxyTreeItem(group, pDocument, !group->isTrashFolder()); ti->setText(0, documentName); + mDocumentUI->documentTreeWidget->editItem(ti,0); } @@ -1401,11 +1440,24 @@ QStringList UBDocumentController::allGroupNames() { QStringList result; - for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) - { - QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); - UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); - result << groupItem->groupName(); + UBDocumentGroupTreeItem* selectedGroup = selectedDocumentGroupTreeItem(); + if(selectedGroup->isDefaultFolder()){ + + for (int i = 0; i < mDocumentUI->documentTreeWidget->topLevelItemCount(); i++) + { + QTreeWidgetItem* item = mDocumentUI->documentTreeWidget->topLevelItem(i); + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + result << groupItem->groupName(); + } + } + else{ + for (int i = 0; i < selectedGroup->childCount(); i++) + { + QTreeWidgetItem* item = selectedGroup->child(i); + UBDocumentGroupTreeItem* groupItem = dynamic_cast(item); + if(groupItem) + result << groupItem->groupName(); + } } return result; diff --git a/src/document/UBDocumentController.h b/src/document/UBDocumentController.h index 786d2829..0b68ee5c 100644 --- a/src/document/UBDocumentController.h +++ b/src/document/UBDocumentController.h @@ -66,6 +66,8 @@ class UBDocumentController : public UBDocumentContainer QString documentTrashGroupName(){ return mDocumentTrashGroupName;} QString defaultDocumentGroupName(){ return mDefaultDocumentGroupName;} + void treeGroupItemRenamed(QString& oldPath,QString& newPath); + signals: void exportDone(); @@ -128,6 +130,14 @@ class UBDocumentController : public UBDocumentContainer QString mDocumentTrashGroupName; QString mDefaultDocumentGroupName; + UBDocumentGroupTreeItem *getCommonGroupItem(QString& path); + QMap mMapOfPaths; + UBDocumentGroupTreeItem* getParentTreeItem(QString& documentGroup); + QList getProxies(QTreeWidgetItem *groupItem); + QList getGroupTreeItem(QTreeWidgetItem* groupItem); + + + private slots: void documentZoomSliderValueChanged (int value); void loadDocumentProxies(); diff --git a/src/document/UBDocumentProxy.cpp b/src/document/UBDocumentProxy.cpp index d5d54d6d..d7b9d969 100644 --- a/src/document/UBDocumentProxy.cpp +++ b/src/document/UBDocumentProxy.cpp @@ -56,7 +56,7 @@ void UBDocumentProxy::init() setMetaData(UBSettings::documentGroupName, ""); QDateTime now = QDateTime::currentDateTime(); - setMetaData(UBSettings::documentName, now.toString(Qt::SystemLocaleShortDate)); + setMetaData(UBSettings::documentName, now.toString(Qt::ISODate)); setUuid(QUuid::createUuid()); diff --git a/src/gui/UBDocumentTreeWidget.cpp b/src/gui/UBDocumentTreeWidget.cpp index 7254a68f..f07795b1 100644 --- a/src/gui/UBDocumentTreeWidget.cpp +++ b/src/gui/UBDocumentTreeWidget.cpp @@ -22,10 +22,10 @@ * along with OpenBoard. If not, see . */ + #include "UBDocumentTreeWidget.h" #include "document/UBDocumentProxy.h" -//#include "document/UBDocumentContainer.h" #include "core/UBSettings.h" #include "core/UBApplication.h" @@ -33,6 +33,9 @@ #include "core/UBMimeData.h" #include "core/UBApplicationController.h" #include "core/UBDocumentManager.h" + +#include "gui/UBMainWindow.h" + #include "document/UBDocumentController.h" #include "adaptors/UBThumbnailAdaptor.h" @@ -41,22 +44,23 @@ #include "core/memcheck.h" +#include + UBDocumentTreeWidget::UBDocumentTreeWidget(QWidget * parent) : QTreeWidget(parent) , mSelectedProxyTi(0) , mDropTargetProxyTi(0) + , mLastItemCompletePath("") { setDragDropMode(QAbstractItemView::InternalMove); setAutoScroll(true); mScrollTimer = new QTimer(this); - connect(UBDocumentManager::documentManager(), SIGNAL(documentUpdated(UBDocumentProxy*)) - , this, SLOT(documentUpdated(UBDocumentProxy*))); + connect(UBDocumentManager::documentManager(), SIGNAL(documentUpdated(UBDocumentProxy*)), this, SLOT(documentUpdated(UBDocumentProxy*))); - connect(this, SIGNAL(itemChanged(QTreeWidgetItem *, int)) - , this, SLOT(itemChangedValidation(QTreeWidgetItem *, int))); - connect(mScrollTimer, SIGNAL(timeout()) - , this, SLOT(autoScroll())); + connect(this, SIGNAL(itemChanged(QTreeWidgetItem *, int)) , this, SLOT(itemChangedValidation(QTreeWidgetItem *, int))); + connect(mScrollTimer, SIGNAL(timeout()) , this, SLOT(autoScroll())); + connect(this,SIGNAL(itemPressed(QTreeWidgetItem*,int)),this,SLOT(onItemPressed(QTreeWidgetItem*,int))); } @@ -66,30 +70,95 @@ UBDocumentTreeWidget::~UBDocumentTreeWidget() } +void UBDocumentTreeWidget::onItemPressed(QTreeWidgetItem* item, int column) +{ + Q_UNUSED(column) + + UBDocumentGroupTreeItem* group = dynamic_cast(item); + if(group){ + mLastItemCompletePath = group->buildEntirePath(); + mLastItemName = group->groupName(); + } +} + void UBDocumentTreeWidget::itemChangedValidation(QTreeWidgetItem * item, int column) { - if (column == 0) + +// QString emptyNameWarningTitle = tr("Empty name"); +// QString emptyNameWarningText = tr("The name should not be empty. Please enter a valid name."); + QString alreadyExistsNameWarningTitle = tr("Name already used"); + QString alreadyExistsNameWarningText = tr("The actual name is in conflict with and existing. Please choose another one."); + + + UBDocumentProxyTreeItem* treeItem = dynamic_cast< UBDocumentProxyTreeItem *>(item); + if (treeItem) { - UBDocumentGroupTreeItem *group = dynamic_cast< UBDocumentGroupTreeItem *>(item); + QString name = treeItem->text(column); +// if(name.isEmpty()) +// UBApplication::mainWindow->warning(emptyNameWarningTitle,emptyNameWarningText); + - if (group) + for(int i = 0; i < treeItem->parent()->childCount(); i++) { - QString name = group->text(0); + QTreeWidgetItem* childAtPosition = treeItem->parent()->child(i); + + if (childAtPosition != item && childAtPosition->text(column) == name){ + UBApplication::mainWindow->warning(alreadyExistsNameWarningTitle,alreadyExistsNameWarningText); + // This is not really a good way but at this time we are not yet out of the editing time + // this is not what is told by the name of the function itemChanged... + mFailedValidationForTreeItem = item; + mFailedValidationItemColumn = column; + QTimer::singleShot(100,this,SLOT(validationFailed())); + return; + } + } + } - for(int i = 0; i < topLevelItemCount (); i++) - { - QTreeWidgetItem *someTopLevelItem = topLevelItem(i); - if (someTopLevelItem != group && - someTopLevelItem->text(0) == name) - { - group->setText(0, tr("%1 (copy)").arg(name)); + UBDocumentGroupTreeItem* group = dynamic_cast(item); + if(group) + { + QString name = group->text(column); +// if(name.isEmpty()) +// UBApplication::mainWindow->warning(emptyNameWarningTitle,emptyNameWarningText); + + if(group->parent()){ + for(int i = 0; i < group->parent()->childCount(); i++) + { + QTreeWidgetItem* childAtPosition = group->parent()->child(i); + + if (childAtPosition != item && childAtPosition->text(column) == name){ + UBApplication::mainWindow->warning(alreadyExistsNameWarningTitle,alreadyExistsNameWarningText); + mFailedValidationForTreeItem = item; + mFailedValidationItemColumn = column; + QTimer::singleShot(100,this,SLOT(validationFailed())); + return; } } } + else{ + // We are looking at the top level items; + for(int i = 0; i < topLevelItemCount(); i += 1){ + if(topLevelItem(i) != item && dynamic_cast(topLevelItem(i))->groupName() == group->groupName()){ + UBApplication::mainWindow->warning(tr("Name already in use"),tr("Please choose another name for the directory. The chosed name is already used.")); + mFailedValidationForTreeItem = item; + mFailedValidationItemColumn = column; + QTimer::singleShot(100,this,SLOT(validationFailed())); + return; + } + + } + } + QString newPath = group->buildEntirePath(); + group->updateChildrenPath(column, mLastItemCompletePath, newPath); + UBApplication::documentController->treeGroupItemRenamed(mLastItemCompletePath, newPath); } } +void UBDocumentTreeWidget::validationFailed() +{ + editItem(mFailedValidationForTreeItem,mFailedValidationItemColumn); +} Qt::DropActions UBDocumentTreeWidget::supportedDropActions() const { @@ -208,11 +277,6 @@ void UBDocumentTreeWidget::dragMoveEvent(QDragMoveEvent *event) void UBDocumentTreeWidget::focusInEvent(QFocusEvent *event) { - Q_UNUSED(event); - - // Tolik - //itemSelectionChanged(); - QTreeWidget::focusInEvent(event); } @@ -275,7 +339,6 @@ void UBDocumentTreeWidget::dropEvent(QDropEvent *event) if (groupItem->isTrashFolder()) mSelectedProxyTi->setFlags(mSelectedProxyTi->flags() ^ Qt::ItemIsEditable); - //clearSelection(); expandItem(groupItem); scrollToItem(mSelectedProxyTi); @@ -320,7 +383,6 @@ void UBDocumentTreeWidget::dropEvent(QDropEvent *event) if (scene) { UBGraphicsScene* sceneClone = scene->sceneDeepCopy(); -// UBGraphicsScene* sceneClone = scene; UBDocumentProxy *targetDocProxy = targetProxyTreeItem->proxy(); @@ -453,6 +515,35 @@ QString UBDocumentGroupTreeItem::groupName() const return text(0); } +QString UBDocumentGroupTreeItem::buildEntirePath() +{ + QString result(groupName()); + UBDocumentGroupTreeItem* item = this; + while(item->parent()){ + item = dynamic_cast(item->parent()); + result = item->groupName() + "/" + result; + } + + return result; +} + +void UBDocumentGroupTreeItem::updateChildrenPath(int column, QString& previousText, const QString& text) +{ + for(int i = 0; i < childCount(); i += 1){ + UBDocumentGroupTreeItem* groupTreeItem = dynamic_cast(child(i)); + if(groupTreeItem) + groupTreeItem->updateChildrenPath(column, previousText,text); + else{ + UBDocumentProxyTreeItem* docProxyItem = dynamic_cast(child(i)); + QString groupName = docProxyItem->proxy()->metaData(UBSettings::documentGroupName).toString(); + groupName = groupName.remove(0,previousText.length()); + groupName = text + groupName; + docProxyItem->proxy()->setMetaData(UBSettings::documentGroupName, groupName); + UBPersistenceManager::persistenceManager()->persistDocumentMetadata(docProxyItem->proxy()); + } + } +} + bool UBDocumentGroupTreeItem::isTrashFolder() const { diff --git a/src/gui/UBDocumentTreeWidget.h b/src/gui/UBDocumentTreeWidget.h index 98a21b4c..a31c9f71 100644 --- a/src/gui/UBDocumentTreeWidget.h +++ b/src/gui/UBDocumentTreeWidget.h @@ -54,8 +54,9 @@ class UBDocumentTreeWidget : public QTreeWidget void documentUpdated(UBDocumentProxy *pDocument); void itemChangedValidation(QTreeWidgetItem * item, int column); - + void onItemPressed(QTreeWidgetItem* item, int column); void autoScroll(); + void validationFailed(); private: UBDocumentProxyTreeItem *mSelectedProxyTi; @@ -63,6 +64,10 @@ class UBDocumentTreeWidget : public QTreeWidget QBrush mBackground; QTimer* mScrollTimer; int mScrollMagnitude; + QTreeWidgetItem* mFailedValidationForTreeItem; + int mFailedValidationItemColumn; + QString mLastItemCompletePath; + QString mLastItemName; }; @@ -93,6 +98,11 @@ class UBDocumentGroupTreeItem : public QTreeWidgetItem bool isTrashFolder() const; bool isDefaultFolder() const; + + QString buildEntirePath(); + + + void updateChildrenPath(int column, QString& previousText, const QString &text); }; #endif /* UBDOCUMENTTREEWIDGET_H_ */