Skip to content

Commit

Permalink
Merge pull request #1809 from KLayout/feature/issue-1776
Browse files Browse the repository at this point in the history
First draft for fix of issue #1776 (undo/redo by list)
  • Loading branch information
klayoutmatthias authored Jul 31, 2024
2 parents 1040e81 + ee9644c commit d1121fa
Show file tree
Hide file tree
Showing 10 changed files with 412 additions and 1 deletion.
67 changes: 66 additions & 1 deletion src/db/db/dbManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ Manager::redo ()
}
}

std::pair<bool, std::string>
std::pair<bool, std::string>
Manager::available_undo () const
{
if (m_opened || m_current == m_transactions.begin ()) {
Expand All @@ -305,6 +305,71 @@ Manager::available_redo () const
}
}

int
Manager::available_undo_items ()
{
if (m_opened) {
return 0;
}

int n = 0;
for (auto i = m_current; i != m_transactions.begin (); --i) {
++n;
}
return n;
}

int
Manager::available_redo_items ()
{
if (m_opened) {
return 0;
}

int n = 0;
for (auto i = m_current; i != m_transactions.end (); ++i) {
++n;
}
return n;
}

std::string
Manager::undo_or_redo_item (int delta) const
{
if (delta < 0) {

auto i = m_current;
while (delta < 0) {
if (i == m_transactions.begin ()) {
return std::string ();
}
++delta;
--i;
}

return i->second;

} else {

auto i = m_current;
while (delta > 0) {
if (i == m_transactions.end ()) {
return std::string ();
}
--delta;
++i;
}

if (i == m_transactions.end ()) {
return std::string ();
} else {
return i->second;
}

}
}


db::Op *
Manager::last_queued (db::Object *object)
{
Expand Down
23 changes: 23 additions & 0 deletions src/db/db/dbManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,29 @@ class DB_PUBLIC Manager
*/
std::pair<bool, std::string> available_redo () const;

/**
* @brief Gets the number of available undo items
*/
int available_undo_items ();

/**
* @brief Gets the number of available redo items
*/
int available_redo_items ();

/**
* @brief Gets an item from the list
*
* @param delta A positive value or 0 for the nth redo item, A negative value for the nth undo item
*
* A delta of "0" will give you the next redo item, a delta of "1" the second next one.
* A delta of "-1" will give you the first undo item.
* delta must be less than "available_redo_items" and larger or equal than "-available_undo_items".
*
* @return The description of the transaction
*/
std::string undo_or_redo_item (int delta) const;

/**
* @brief Queue a operation for undo
*
Expand Down
2 changes: 2 additions & 0 deletions src/lay/lay/gsiDeclLayMainWindow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ static const char *cm_symbols[] = {
"cm_unselect_all",
"cm_undo",
"cm_redo",
"cm_undo_list",
"cm_redo_list",
"cm_delete",
"cm_show_properties",
"cm_copy",
Expand Down
56 changes: 56 additions & 0 deletions src/lay/lay/layMainWindow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1707,6 +1707,27 @@ MainWindow::cm_undo ()
}
}

void
MainWindow::cm_undo_list ()
{
if (current_view () && m_manager.available_undo ().first) {

std::unique_ptr<lay::UndoRedoListForm> dialog (new lay::UndoRedoListForm (this, &m_manager, true));

int steps = 0;
if (dialog->exec (steps)) {
for (std::vector <lay::LayoutViewWidget *>::iterator vp = mp_views.begin (); vp != mp_views.end (); ++vp) {
(*vp)->view ()->clear_selection ();
(*vp)->view ()->cancel ();
}
while (steps-- > 0) {
m_manager.undo ();
}
}

}
}

void
MainWindow::cm_redo ()
{
Expand All @@ -1719,6 +1740,27 @@ MainWindow::cm_redo ()
}
}

void
MainWindow::cm_redo_list ()
{
if (current_view () && m_manager.available_redo ().first) {

std::unique_ptr<lay::UndoRedoListForm> dialog (new lay::UndoRedoListForm (this, &m_manager, false));

int steps = 0;
if (dialog->exec (steps)) {
for (std::vector <lay::LayoutViewWidget *>::iterator vp = mp_views.begin (); vp != mp_views.end (); ++vp) {
(*vp)->view ()->clear_selection ();
(*vp)->view ()->cancel ();
}
while (steps-- > 0) {
m_manager.redo ();
}
}

}
}

void
MainWindow::cm_goto_position ()
{
Expand Down Expand Up @@ -1847,6 +1889,11 @@ MainWindow::update_action_states ()
undo_action->set_title (undo_txt);
undo_action->set_enabled (undo_enable && edits_enabled ());

if (menu ()->is_valid ("edit_menu.undo_list")) {
Action *undo_list_action = menu ()->action ("edit_menu.undo_list");
undo_list_action->set_enabled (undo_enable && edits_enabled ());
}

}

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

if (menu ()->is_valid ("edit_menu.redo_list")) {
Action *redo_list_action = menu ()->action ("edit_menu.redo_list");
redo_list_action->set_enabled (redo_enable && edits_enabled ());
}

}

if (menu ()->is_valid ("edit_menu.paste")) {
Expand Down Expand Up @@ -3922,6 +3974,10 @@ MainWindow::menu_activated (const std::string &symbol)
cm_undo ();
} else if (symbol == "cm_redo") {
cm_redo ();
} else if (symbol == "cm_undo_list") {
cm_undo_list ();
} else if (symbol == "cm_redo_list") {
cm_redo_list ();
} else if (symbol == "cm_goto_position") {
cm_goto_position ();
} else if (symbol == "cm_manage_bookmarks") {
Expand Down
2 changes: 2 additions & 0 deletions src/lay/lay/layMainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,8 @@ protected slots:
void cm_reset_window_state ();
void cm_undo ();
void cm_redo ();
void cm_undo_list ();
void cm_redo_list ();
void cm_goto_position ();
void cm_manage_bookmarks ();
void cm_bookmark_view ();
Expand Down
97 changes: 97 additions & 0 deletions src/layui/layui/UndoRedoListForm.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UndoRedoListForm</class>
<widget class="QDialog" name="UndoRedoListForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>307</width>
<height>320</height>
</rect>
</property>
<property name="windowTitle">
<string>Undo / Redo by List</string>
</property>
<layout class="QGridLayout">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="title_lbl">
<property name="text">
<string>(tbd)</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QListView" name="items">
<property name="uniformItemSizes">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<tabstops>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>UndoRedoListForm</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>211</x>
<y>282</y>
</hint>
<hint type="destinationlabel">
<x>211</x>
<y>152</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>UndoRedoListForm</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>211</x>
<y>282</y>
</hint>
<hint type="destinationlabel">
<x>211</x>
<y>152</y>
</hint>
</hints>
</connection>
</connections>
</ui>
Loading

0 comments on commit d1121fa

Please sign in to comment.