1 /**********************************************************************************************
2     Copyright (C) 2014 Oliver Eichler <oliver.eichler@gmx.de>
3 
4     This program is free software: you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation, either version 3 of the License, or
7     (at your option) any later version.
8 
9     This program 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
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 
17 **********************************************************************************************/
18 
19 #include "gis/CGisWorkspace.h"
20 #include "gis/prj/IGisProject.h"
21 #include "widgets/CHistoryListWidget.h"
22 
23 #include "CMainWindow.h"
24 
25 #include <QtWidgets>
26 
CHistoryListWidget(QWidget * parent)27 CHistoryListWidget::CHistoryListWidget(QWidget* parent)
28     : QListWidget(parent)
29 {
30     setIconSize(QSize(32, 32));
31     setContextMenuPolicy(Qt::CustomContextMenu);
32     connect(this, &CHistoryListWidget::itemSelectionChanged, this, &CHistoryListWidget::slotSelectionChanged);
33     connect(this, &CHistoryListWidget::customContextMenuRequested, this, &CHistoryListWidget::slotContextMenu);
34 
35     menu = new QMenu(this);
36 
37     actionCutHistoryBefore = menu->addAction(
38         QIcon("://icons/32x32/CutHistoryBefore.png"),
39         tr("Cut history before"),
40         this,
41         &CHistoryListWidget::slotCutHistoryBefore);
42     actionCutHistoryAfter = menu->addAction(
43         QIcon("://icons/32x32/CutHistoryAfter.png"),
44         tr("Cut history after"),
45         this,
46         &CHistoryListWidget::slotCutHistoryAfter);
47 }
48 
~CHistoryListWidget()49 CHistoryListWidget::~CHistoryListWidget()
50 {
51 }
52 
setupHistory(IGisItem & gisItem)53 void CHistoryListWidget::setupHistory(IGisItem& gisItem)
54 {
55     blockSignals(true);
56     clear();
57 
58     key = gisItem.getKey();
59 
60     const IGisItem::history_t& history = gisItem.getHistory();
61 
62     //for(const IGisItem::history_event_t& event : history.events)
63     for(int i = 0; i < history.events.size(); i++)
64     {
65         const IGisItem::history_event_t& event = history.events[i];
66 
67         QString str;
68         QListWidgetItem* item = new QListWidgetItem(this);
69 
70         str = event.time.toString();
71         if(!event.who.isEmpty())
72         {
73             str += tr(" by %1").arg(event.who);
74         }
75 
76         str += "\n";
77         str += event.comment;
78 
79         item->setText(str);
80         item->setIcon(QIcon(event.icon));
81         if(event.data.isEmpty())
82         {
83             item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
84         }
85     }
86 
87     if(history.histIdxCurrent < count())
88     {
89         setCurrentItem(item(history.histIdxCurrent));
90     }
91     blockSignals(false);
92 }
93 
slotSelectionChanged()94 void CHistoryListWidget::slotSelectionChanged()
95 {
96     IGisItem* item = CGisWorkspace::self().getItemByKey(key);
97     if(nullptr == item)
98     {
99         return;
100     }
101 
102     item->loadHistory(currentRow());
103     item->updateDecoration(IGisItem::eMarkChanged, IGisItem::eMarkNone);
104 
105     emit sigChanged();
106 }
107 
slotContextMenu(const QPoint & point)108 void CHistoryListWidget::slotContextMenu(const QPoint& point)
109 {
110     if ((count() == 0) || (count() == 1)) // nothing can be done if there is 0 (should not happen) or 1 event in history
111     {
112         return;
113     }
114 
115     actionCutHistoryBefore->setEnabled(currentRow() > 0);
116     actionCutHistoryAfter->setEnabled(currentRow() < count() - 1);
117 
118     QPoint p = mapToGlobal(point);
119     menu->exec(p);
120 }
121 
122 
slotCutHistoryAfter()123 void CHistoryListWidget::slotCutHistoryAfter()
124 {
125     if(currentRow() == (count() - 1))
126     {
127         return;
128     }
129 
130     IGisItem* item = CGisWorkspace::self().getItemByKey(key);
131     if(nullptr == item)
132     {
133         return;
134     }
135 
136     item->cutHistoryAfter();
137     item->updateDecoration(IGisItem::eMarkChanged, IGisItem::eMarkNone);
138 
139     IGisProject* project = dynamic_cast<IGisProject*>(item->parent());
140     if(project)
141     {
142         project->setChanged();
143     }
144 
145     emit sigChanged();
146 }
147 
148 
149 
slotCutHistoryBefore()150 void CHistoryListWidget::slotCutHistoryBefore()
151 {
152     if (currentRow() == 0)
153     {
154         return;
155     }
156 
157     IGisItem* item = CGisWorkspace::self().getItemByKey(key);
158     if (nullptr == item)
159     {
160         return;
161     }
162 
163     int res = QMessageBox::warning(CMainWindow::getBestWidgetForParent(), tr("History removal")
164                                    , tr("The removal is permanent and cannot be undone. "
165                                         "<b>Do you really want to delete history before this step?</b>")
166                                    , QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
167     if (res == QMessageBox::No)
168     {
169         return;
170     }
171 
172     item->cutHistoryBefore();
173     item->updateDecoration(IGisItem::eMarkChanged, IGisItem::eMarkNone);
174 
175     IGisProject* project = dynamic_cast<IGisProject*>(item->parent());
176     if (project)
177     {
178         project->setChanged();
179     }
180 
181     emit sigChanged();
182 }
183