Skip to content

Commit d1121fa

Browse files
Merge pull request #1809 from KLayout/feature/issue-1776
First draft for fix of issue #1776 (undo/redo by list)
2 parents 1040e81 + ee9644c commit d1121fa

10 files changed

Lines changed: 412 additions & 1 deletion

File tree

src/db/db/dbManager.cc

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ Manager::redo ()
283283
}
284284
}
285285

286-
std::pair<bool, std::string>
286+
std::pair<bool, std::string>
287287
Manager::available_undo () const
288288
{
289289
if (m_opened || m_current == m_transactions.begin ()) {
@@ -305,6 +305,71 @@ Manager::available_redo () const
305305
}
306306
}
307307

308+
int
309+
Manager::available_undo_items ()
310+
{
311+
if (m_opened) {
312+
return 0;
313+
}
314+
315+
int n = 0;
316+
for (auto i = m_current; i != m_transactions.begin (); --i) {
317+
++n;
318+
}
319+
return n;
320+
}
321+
322+
int
323+
Manager::available_redo_items ()
324+
{
325+
if (m_opened) {
326+
return 0;
327+
}
328+
329+
int n = 0;
330+
for (auto i = m_current; i != m_transactions.end (); ++i) {
331+
++n;
332+
}
333+
return n;
334+
}
335+
336+
std::string
337+
Manager::undo_or_redo_item (int delta) const
338+
{
339+
if (delta < 0) {
340+
341+
auto i = m_current;
342+
while (delta < 0) {
343+
if (i == m_transactions.begin ()) {
344+
return std::string ();
345+
}
346+
++delta;
347+
--i;
348+
}
349+
350+
return i->second;
351+
352+
} else {
353+
354+
auto i = m_current;
355+
while (delta > 0) {
356+
if (i == m_transactions.end ()) {
357+
return std::string ();
358+
}
359+
--delta;
360+
++i;
361+
}
362+
363+
if (i == m_transactions.end ()) {
364+
return std::string ();
365+
} else {
366+
return i->second;
367+
}
368+
369+
}
370+
}
371+
372+
308373
db::Op *
309374
Manager::last_queued (db::Object *object)
310375
{

src/db/db/dbManager.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,29 @@ class DB_PUBLIC Manager
202202
*/
203203
std::pair<bool, std::string> available_redo () const;
204204

205+
/**
206+
* @brief Gets the number of available undo items
207+
*/
208+
int available_undo_items ();
209+
210+
/**
211+
* @brief Gets the number of available redo items
212+
*/
213+
int available_redo_items ();
214+
215+
/**
216+
* @brief Gets an item from the list
217+
*
218+
* @param delta A positive value or 0 for the nth redo item, A negative value for the nth undo item
219+
*
220+
* A delta of "0" will give you the next redo item, a delta of "1" the second next one.
221+
* A delta of "-1" will give you the first undo item.
222+
* delta must be less than "available_redo_items" and larger or equal than "-available_undo_items".
223+
*
224+
* @return The description of the transaction
225+
*/
226+
std::string undo_or_redo_item (int delta) const;
227+
205228
/**
206229
* @brief Queue a operation for undo
207230
*

src/lay/lay/gsiDeclLayMainWindow.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ static const char *cm_symbols[] = {
5151
"cm_unselect_all",
5252
"cm_undo",
5353
"cm_redo",
54+
"cm_undo_list",
55+
"cm_redo_list",
5456
"cm_delete",
5557
"cm_show_properties",
5658
"cm_copy",

src/lay/lay/layMainWindow.cc

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,6 +1707,27 @@ MainWindow::cm_undo ()
17071707
}
17081708
}
17091709

1710+
void
1711+
MainWindow::cm_undo_list ()
1712+
{
1713+
if (current_view () && m_manager.available_undo ().first) {
1714+
1715+
std::unique_ptr<lay::UndoRedoListForm> dialog (new lay::UndoRedoListForm (this, &m_manager, true));
1716+
1717+
int steps = 0;
1718+
if (dialog->exec (steps)) {
1719+
for (std::vector <lay::LayoutViewWidget *>::iterator vp = mp_views.begin (); vp != mp_views.end (); ++vp) {
1720+
(*vp)->view ()->clear_selection ();
1721+
(*vp)->view ()->cancel ();
1722+
}
1723+
while (steps-- > 0) {
1724+
m_manager.undo ();
1725+
}
1726+
}
1727+
1728+
}
1729+
}
1730+
17101731
void
17111732
MainWindow::cm_redo ()
17121733
{
@@ -1719,6 +1740,27 @@ MainWindow::cm_redo ()
17191740
}
17201741
}
17211742

1743+
void
1744+
MainWindow::cm_redo_list ()
1745+
{
1746+
if (current_view () && m_manager.available_redo ().first) {
1747+
1748+
std::unique_ptr<lay::UndoRedoListForm> dialog (new lay::UndoRedoListForm (this, &m_manager, false));
1749+
1750+
int steps = 0;
1751+
if (dialog->exec (steps)) {
1752+
for (std::vector <lay::LayoutViewWidget *>::iterator vp = mp_views.begin (); vp != mp_views.end (); ++vp) {
1753+
(*vp)->view ()->clear_selection ();
1754+
(*vp)->view ()->cancel ();
1755+
}
1756+
while (steps-- > 0) {
1757+
m_manager.redo ();
1758+
}
1759+
}
1760+
1761+
}
1762+
}
1763+
17221764
void
17231765
MainWindow::cm_goto_position ()
17241766
{
@@ -1847,6 +1889,11 @@ MainWindow::update_action_states ()
18471889
undo_action->set_title (undo_txt);
18481890
undo_action->set_enabled (undo_enable && edits_enabled ());
18491891

1892+
if (menu ()->is_valid ("edit_menu.undo_list")) {
1893+
Action *undo_list_action = menu ()->action ("edit_menu.undo_list");
1894+
undo_list_action->set_enabled (undo_enable && edits_enabled ());
1895+
}
1896+
18501897
}
18511898

18521899
if (menu ()->is_valid ("edit_menu.redo")) {
@@ -1862,6 +1909,11 @@ MainWindow::update_action_states ()
18621909
redo_action->set_title (redo_txt);
18631910
redo_action->set_enabled (redo_enable && edits_enabled ());
18641911

1912+
if (menu ()->is_valid ("edit_menu.redo_list")) {
1913+
Action *redo_list_action = menu ()->action ("edit_menu.redo_list");
1914+
redo_list_action->set_enabled (redo_enable && edits_enabled ());
1915+
}
1916+
18651917
}
18661918

18671919
if (menu ()->is_valid ("edit_menu.paste")) {
@@ -3922,6 +3974,10 @@ MainWindow::menu_activated (const std::string &symbol)
39223974
cm_undo ();
39233975
} else if (symbol == "cm_redo") {
39243976
cm_redo ();
3977+
} else if (symbol == "cm_undo_list") {
3978+
cm_undo_list ();
3979+
} else if (symbol == "cm_redo_list") {
3980+
cm_redo_list ();
39253981
} else if (symbol == "cm_goto_position") {
39263982
cm_goto_position ();
39273983
} else if (symbol == "cm_manage_bookmarks") {

src/lay/lay/layMainWindow.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,8 @@ protected slots:
800800
void cm_reset_window_state ();
801801
void cm_undo ();
802802
void cm_redo ();
803+
void cm_undo_list ();
804+
void cm_redo_list ();
803805
void cm_goto_position ();
804806
void cm_manage_bookmarks ();
805807
void cm_bookmark_view ();
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>UndoRedoListForm</class>
4+
<widget class="QDialog" name="UndoRedoListForm">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>307</width>
10+
<height>320</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>Undo / Redo by List</string>
15+
</property>
16+
<layout class="QGridLayout">
17+
<property name="leftMargin">
18+
<number>9</number>
19+
</property>
20+
<property name="topMargin">
21+
<number>9</number>
22+
</property>
23+
<property name="rightMargin">
24+
<number>9</number>
25+
</property>
26+
<property name="bottomMargin">
27+
<number>9</number>
28+
</property>
29+
<property name="spacing">
30+
<number>6</number>
31+
</property>
32+
<item row="0" column="0" colspan="2">
33+
<widget class="QLabel" name="title_lbl">
34+
<property name="text">
35+
<string>(tbd)</string>
36+
</property>
37+
</widget>
38+
</item>
39+
<item row="2" column="0" colspan="2">
40+
<widget class="QDialogButtonBox" name="buttonBox">
41+
<property name="orientation">
42+
<enum>Qt::Horizontal</enum>
43+
</property>
44+
<property name="standardButtons">
45+
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
46+
</property>
47+
</widget>
48+
</item>
49+
<item row="1" column="0" colspan="2">
50+
<widget class="QListView" name="items">
51+
<property name="uniformItemSizes">
52+
<bool>true</bool>
53+
</property>
54+
</widget>
55+
</item>
56+
</layout>
57+
</widget>
58+
<layoutdefault spacing="6" margin="11"/>
59+
<tabstops>
60+
<tabstop>buttonBox</tabstop>
61+
</tabstops>
62+
<resources/>
63+
<connections>
64+
<connection>
65+
<sender>buttonBox</sender>
66+
<signal>accepted()</signal>
67+
<receiver>UndoRedoListForm</receiver>
68+
<slot>accept()</slot>
69+
<hints>
70+
<hint type="sourcelabel">
71+
<x>211</x>
72+
<y>282</y>
73+
</hint>
74+
<hint type="destinationlabel">
75+
<x>211</x>
76+
<y>152</y>
77+
</hint>
78+
</hints>
79+
</connection>
80+
<connection>
81+
<sender>buttonBox</sender>
82+
<signal>rejected()</signal>
83+
<receiver>UndoRedoListForm</receiver>
84+
<slot>reject()</slot>
85+
<hints>
86+
<hint type="sourcelabel">
87+
<x>211</x>
88+
<y>282</y>
89+
</hint>
90+
<hint type="destinationlabel">
91+
<x>211</x>
92+
<y>152</y>
93+
</hint>
94+
</hints>
95+
</connection>
96+
</connections>
97+
</ui>

0 commit comments

Comments
 (0)