1 /* This file is part of the KDE project
2    Copyright 2009 Johannes Simon <johannes.simon@gmail.com>
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public
6    License as published by the Free Software Foundation; either
7    version 2 of the License, or (at your option) any later version.
8 
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13 
14    You should have received a copy of the GNU Library General Public License
15    along with this library; see the file COPYING.LIB.  If not, write to
16    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17    Boston, MA 02110-1301, USA.
18 */
19 
20 // Ours
21 #include "SheetAccessModel.h"
22 #include "calligra_sheets_limits.h"
23 #include "Map.h"
24 #include "Binding.h"
25 #include "BindingManager.h"
26 #include "Damages.h"
27 #include "Region.h"
28 
29 // Qt
30 #include <QList>
31 #include <QMap>
32 #include <QStandardItem>
33 #include <QAbstractItemModel>
34 #include <QVariant>
35 
36 // Calligra
37 //#include <KoStore.h>
38 //#include <KoXmlWriter.h>
39 //#include <KoShapeSavingContext.h>
40 
41 Q_DECLARE_METATYPE(QPointer<QAbstractItemModel>)
42 
43 namespace Calligra
44 {
45 namespace Sheets
46 {
47 
48 class SheetAccessModel::Private
49 {
50 public:
51     Map *map;
52     /// Stores in what column each Sheet is. We need this because
53     /// a Sheet is removed from its Map before the sheetRemoved() signal
54     /// is emitted, thus we can't ask the Map what index it had.
55     QMap<Sheet*, int> cols;
56 };
57 
SheetAccessModel(Map * map)58 SheetAccessModel::SheetAccessModel(Map *map)
59         : d(new Private)
60 {
61     d->map = map;
62 
63     connect(map, SIGNAL(sheetAdded(Sheet*)),
64             this, SLOT(slotSheetAdded(Sheet*)));
65     // FIXME: Check if we can simply connect sheetRevived() to slotSheetAdded()
66     connect(map, SIGNAL(sheetRevived(Sheet*)),
67             this, SLOT(slotSheetAdded(Sheet*)));
68     connect(map, SIGNAL(sheetRemoved(Sheet*)),
69             this, SLOT(slotSheetRemoved(Sheet*)));
70     connect(map, SIGNAL(damagesFlushed(QList<Damage*>)),
71             this, SLOT(handleDamages(QList<Damage*>)));
72 
73     setRowCount(1);
74     setColumnCount(0);
75 }
76 
~SheetAccessModel()77 SheetAccessModel::~SheetAccessModel()
78 {
79     delete d;
80 }
81 
slotSheetAdded(Sheet * sheet)82 void SheetAccessModel::slotSheetAdded(Sheet *sheet)
83 {
84     Q_ASSERT(!d->cols.contains(sheet));
85 
86     QStandardItem *item = new QStandardItem;
87     QList<QStandardItem*> col;
88     col.append(item);
89 
90     // This region contains the entire sheet
91     const Region region(1, 1, KS_colMax, KS_rowMax, sheet);
92     const QPointer<QAbstractItemModel> model = const_cast<QAbstractItemModel*>( d->map->bindingManager()->createModel( region.name() ) );
93 
94     item->setData( QVariant::fromValue( model ), Qt::DisplayRole );
95 
96     const int sheetIndex = d->map->indexOf( sheet );
97     d->cols.insert(sheet, sheetIndex);
98 
99     insertColumn( sheetIndex, col );
100     setHeaderData( sheetIndex, Qt::Horizontal, sheet->sheetName() );
101 }
102 
slotSheetRemoved(Sheet * sheet)103 void SheetAccessModel::slotSheetRemoved(Sheet *sheet)
104 {
105     Q_ASSERT(d->cols.contains(sheet));
106     removeColumn(d->cols[sheet]);
107     d->cols.remove(sheet);
108 }
109 
handleDamages(const QList<Damage * > & damages)110 void SheetAccessModel::handleDamages(const QList<Damage*>& damages)
111 {
112     QList<Damage*>::ConstIterator end(damages.end());
113     for (QList<Damage*>::ConstIterator it = damages.begin(); it != end; ++it) {
114         Damage* damage = *it;
115         if (!damage) {
116             continue;
117         }
118 
119         if (damage->type() == Damage::Sheet) {
120             SheetDamage* sheetDamage = static_cast<SheetDamage*>(damage);
121             debugSheetsDamage << "Processing\t" << *sheetDamage;
122 
123             if (sheetDamage->changes() & SheetDamage::Name) {
124                 Sheet *sheet = sheetDamage->sheet();
125                 // We should never receive signals from sheets that are not in our model
126                 Q_ASSERT(d->cols.contains(sheet));
127                 const int sheetIndex = d->cols[sheet];
128                 setHeaderData(sheetIndex, Qt::Horizontal, sheet->sheetName());
129             }
130             continue;
131         }
132     }
133 }
134 
135 } // namespace Sheets
136 } // namespace Calligra
137