File indexing completed on 2024-05-12 15:26:40
0001 /*************************************************************************** 0002 File : Workbook.h 0003 Project : LabPlot 0004 Description : Aspect providing a container for storing data 0005 in form of spreadsheets and matrices 0006 -------------------------------------------------------------------- 0007 Copyright : (C) 2015 Alexander Semke(alexander.semke@web.de) 0008 0009 ***************************************************************************/ 0010 0011 /*************************************************************************** 0012 * * 0013 * This program is free software; you can redistribute it and/or modify * 0014 * it under the terms of the GNU General Public License as published by * 0015 * the Free Software Foundation; either version 2 of the License, or * 0016 * (at your option) any later version. * 0017 * * 0018 * This program is distributed in the hope that it will be useful, * 0019 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0021 * GNU General Public License for more details. * 0022 * * 0023 * You should have received a copy of the GNU General Public License * 0024 * along with this program; if not, write to the Free Software * 0025 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0026 * Boston, MA 02110-1301 USA * 0027 * * 0028 ***************************************************************************/ 0029 0030 #include "Workbook.h" 0031 #include "backend/spreadsheet/Spreadsheet.h" 0032 #include "backend/matrix/Matrix.h" 0033 #include "backend/lib/XmlStreamReader.h" 0034 #include "commonfrontend/workbook/WorkbookView.h" 0035 #include "kdefrontend/spreadsheet/ExportSpreadsheetDialog.h" 0036 0037 #include <QIcon> 0038 #include <KLocalizedString> 0039 0040 /** 0041 * \class Workbook 0042 * \brief Top-level container for Spreadsheet and Matrix. 0043 * \ingroup backend 0044 */ 0045 Workbook::Workbook(const QString& name) : AbstractPart(name, AspectType::Workbook) { 0046 } 0047 0048 QIcon Workbook::icon() const { 0049 return QIcon::fromTheme("labplot-workbook"); 0050 } 0051 0052 /*! 0053 * Returns a new context menu. The caller takes ownership of the menu. 0054 */ 0055 QMenu* Workbook::createContextMenu() { 0056 QMenu *menu = AbstractPart::createContextMenu(); 0057 Q_ASSERT(menu); 0058 emit requestProjectContextMenu(menu); 0059 return menu; 0060 } 0061 0062 QWidget* Workbook::view() const { 0063 if (!m_partView) { 0064 m_view = new WorkbookView(const_cast<Workbook*>(this)); 0065 m_partView = m_view; 0066 } 0067 return m_partView; 0068 } 0069 0070 bool Workbook::exportView() const { 0071 Spreadsheet* s = currentSpreadsheet(); 0072 bool ret = false; 0073 if (s) 0074 ret = s->exportView(); 0075 else { 0076 Matrix* m = currentMatrix(); 0077 if (m) 0078 ret = m->exportView(); 0079 } 0080 return ret; 0081 } 0082 0083 bool Workbook::printView() { 0084 Spreadsheet* s = currentSpreadsheet(); 0085 bool ret = false; 0086 if (s) 0087 ret = s->printView(); 0088 else { 0089 Matrix* m = currentMatrix(); 0090 if (m) 0091 ret = m->printView(); 0092 } 0093 return ret; 0094 } 0095 0096 bool Workbook::printPreview() const { 0097 Spreadsheet* s = currentSpreadsheet(); 0098 bool ret = false; 0099 if (s) 0100 ret = s->printPreview(); 0101 else { 0102 Matrix* m = currentMatrix(); 0103 if (m) 0104 ret = m->printPreview(); 0105 } 0106 return ret; 0107 } 0108 0109 Spreadsheet* Workbook::currentSpreadsheet() const { 0110 if (!m_view) 0111 return nullptr; 0112 0113 int index = m_view->currentIndex(); 0114 if (index != -1) { 0115 auto* aspect = child<AbstractAspect>(index); 0116 return dynamic_cast<Spreadsheet*>(aspect); 0117 } 0118 return nullptr; 0119 } 0120 0121 Matrix* Workbook::currentMatrix() const { 0122 if (!m_view) 0123 return nullptr; 0124 0125 int index = reinterpret_cast<const WorkbookView*>(m_view)->currentIndex(); 0126 if (index != -1) { 0127 auto* aspect = child<AbstractAspect>(index); 0128 return dynamic_cast<Matrix*>(aspect); 0129 } 0130 return nullptr; 0131 } 0132 0133 /*! 0134 this slot is called when a workbook child is selected in the project explorer. 0135 emits \c workbookItemSelected() to forward this event to the \c WorkbookView 0136 in order to select the corresponding tab. 0137 */ 0138 void Workbook::childSelected(const AbstractAspect* aspect) { 0139 int index = indexOfChild<AbstractAspect>(aspect); 0140 emit workbookItemSelected(index); 0141 } 0142 0143 /*! 0144 this slot is called when a worksheet element is deselected in the project explorer. 0145 */ 0146 void Workbook::childDeselected(const AbstractAspect* aspect) { 0147 Q_UNUSED(aspect); 0148 } 0149 0150 /*! 0151 * Emits the signal to select or to deselect the workbook item (spreadsheet or matrix) with the index \c index 0152 * in the project explorer, if \c selected=true or \c selected=false, respectively. 0153 * The signal is handled in \c AspectTreeModel and forwarded to the tree view in \c ProjectExplorer. 0154 * This function is called in \c WorkbookView when the current tab was changed 0155 */ 0156 void Workbook::setChildSelectedInView(int index, bool selected) { 0157 auto* aspect = child<AbstractAspect>(index); 0158 if (selected) { 0159 emit childAspectSelectedInView(aspect); 0160 0161 //deselect the workbook in the project explorer, if a child (spreadsheet or matrix) was selected. 0162 //prevents unwanted multiple selection with workbook if it was selected before. 0163 emit childAspectDeselectedInView(this); 0164 } else { 0165 emit childAspectDeselectedInView(aspect); 0166 0167 //deselect also all children that were potentially selected before (columns of a spreadsheet) 0168 for (auto* child : aspect->children<AbstractAspect>()) 0169 emit childAspectDeselectedInView(child); 0170 } 0171 } 0172 0173 //############################################################################## 0174 //################## Serialization/Deserialization ########################### 0175 //############################################################################## 0176 0177 //! Save as XML 0178 void Workbook::save(QXmlStreamWriter* writer) const { 0179 writer->writeStartElement( "workbook" ); 0180 writeBasicAttributes(writer); 0181 writeCommentElement(writer); 0182 0183 //serialize all children 0184 for (auto* aspect : children<AbstractAspect>()) 0185 aspect->save(writer); 0186 0187 writer->writeEndElement(); // close "workbook" section 0188 } 0189 0190 //! Load from XML 0191 bool Workbook::load(XmlStreamReader* reader, bool preview) { 0192 if (!readBasicAttributes(reader)) 0193 return false; 0194 0195 while (!reader->atEnd()) { 0196 reader->readNext(); 0197 if (reader->isEndElement() && reader->name() == "workbook") 0198 break; 0199 0200 if (!reader->isStartElement()) 0201 continue; 0202 0203 if (reader->name() == "comment") { 0204 if (!readCommentElement(reader)) 0205 return false; 0206 } else if (reader->name() == "spreadsheet") { 0207 Spreadsheet* spreadsheet = new Spreadsheet("spreadsheet", true); 0208 if (!spreadsheet->load(reader, preview)) { 0209 delete spreadsheet; 0210 return false; 0211 } else 0212 addChild(spreadsheet); 0213 } else if (reader->name() == "matrix") { 0214 Matrix* matrix = new Matrix(i18n("matrix"), true); 0215 if (!matrix->load(reader, preview)) { 0216 delete matrix; 0217 return false; 0218 } else 0219 addChild(matrix); 0220 } else { // unknown element 0221 reader->raiseWarning(i18n("unknown workbook element '%1'", reader->name().toString())); 0222 if (!reader->skipToEndElement()) return false; 0223 } 0224 } 0225 0226 return true; 0227 }