Wed, 10 Apr 2013 19:26:14 +0300
Added history dialog, cannot display all types yet
gui.cpp | file | annotate | diff | comparison | revisions | |
gui.h | file | annotate | diff | comparison | revisions | |
gui_editactions.cpp | file | annotate | diff | comparison | revisions | |
history.cpp | file | annotate | diff | comparison | revisions | |
history.h | file | annotate | diff | comparison | revisions | |
icons/history.png | file | annotate | diff | comparison | revisions | |
ldforge.pro | file | annotate | diff | comparison | revisions | |
ldtypes.cpp | file | annotate | diff | comparison | revisions | |
ldtypes.h | file | annotate | diff | comparison | revisions | |
zz_historyDialog.cpp | file | annotate | diff | comparison | revisions | |
zz_historyDialog.h | file | annotate | diff | comparison | revisions |
--- a/gui.cpp Wed Apr 10 16:17:22 2013 +0300 +++ b/gui.cpp Wed Apr 10 19:26:14 2013 +0300 @@ -58,6 +58,7 @@ EXTERN_ACTION (aboutQt) EXTERN_ACTION (undo) EXTERN_ACTION (redo) +EXTERN_ACTION (showHistory) vector<actionmeta> g_ActionMeta; @@ -177,6 +178,10 @@ ADD_MENU_ITEM (Edit, setContents) // Set Contents ADD_MENU_ITEM (Edit, makeBorders) // Make Borders + // Control menuBar + qControlMenu = menuBar ()->addMenu (tr ("&Control")); + ADD_MENU_ITEM (Control, showHistory) // Show History + // Help menu qHelpMenu = menuBar ()->addMenu (tr ("&Help")); ADD_MENU_ITEM (Help, help) // Help
--- a/gui.h Wed Apr 10 16:17:22 2013 +0300 +++ b/gui.h Wed Apr 10 19:26:14 2013 +0300 @@ -58,7 +58,7 @@ static void actionHandler_##NAME () #define EXTERN_ACTION(NAME) extern QAction* ACTION_NAME (NAME); -#define ACTION_NAME(N) (LDForgeAction_##N) +#define ACTION_NAME(N) LDForgeAction_##N // Convenience macros for key sequences. #define KEY(N) (Qt::Key_##N) @@ -99,7 +99,7 @@ // Object list view QTreeWidget* qObjList; QTextEdit* qMessageLog; - QMenu* qFileMenu, *qEditMenu, *qInsertMenu, *qHelpMenu; + QMenu* qFileMenu, *qEditMenu, *qInsertMenu, *qHelpMenu, *qControlMenu; std::vector<QToolBar*> qaToolBars; str zMessageLogHTML;
--- a/gui_editactions.cpp Wed Apr 10 16:17:22 2013 +0300 +++ b/gui_editactions.cpp Wed Apr 10 19:26:14 2013 +0300 @@ -18,10 +18,11 @@ #include "gui.h" #include "common.h" +#include "file.h" +#include "history.h" +#include "zz_colorSelectDialog.h" +#include "zz_historyDialog.h" #include "zz_setContentsDialog.h" -#include "file.h" -#include "zz_colorSelectDialog.h" -#include "history.h" vector<LDObject*> g_Clipboard; @@ -322,10 +323,18 @@ doMoveSelection (false); } +// ============================================================================= +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// ============================================================================= ACTION (undo, "Undo", "undo", "Undo a step.", CTRL (Z)) { History::undo (); } ACTION (redo, "Redo", "redo", "Redo a step.", CTRL_SHIFT (Z)) { History::redo (); +} + +ACTION (showHistory, "Show History", "history", "Show the history dialog.", (0)) { + HistoryDialog dlg; + dlg.exec (); } \ No newline at end of file
--- a/history.cpp Wed Apr 10 16:17:22 2013 +0300 +++ b/history.cpp Wed Apr 10 19:26:14 2013 +0300 @@ -37,7 +37,6 @@ void addEntry (HistoryEntry* entry) { // If there's any entries after our current position, we need to remove them now for (ulong i = lPos + 1; i < entries.size(); ++i) { - delete entries[i]; entries.erase (entries.begin() + i); } @@ -67,6 +66,16 @@ } // ========================================================================= + void clear () { + for (HistoryEntry* entry : entries) + delete entry; + + entries.clear (); + lPos = -1; + updateActions (); + } + + // ========================================================================= void updateActions () { ACTION_NAME (undo)->setEnabled (lPos > -1); ACTION_NAME (redo)->setEnabled (lPos < (long) entries.size () - 1);
--- a/history.h Wed Apr 10 16:17:22 2013 +0300 +++ b/history.h Wed Apr 10 19:26:14 2013 +0300 @@ -25,8 +25,18 @@ #define IMPLEMENT_HISTORY_TYPE(N) \ virtual ~N##History (); \ virtual void undo (); \ - virtual void redo (); + virtual void redo (); \ + virtual HistoryType type () { return HISTORY_##N; } +// ============================================================================= +enum HistoryType { + HISTORY_Delete, + HISTORY_SetColor, + HISTORY_SetContents, + HISTORY_ListMove, + HISTORY_Addition, + HISTORY_QuadSplit, +}; // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -36,6 +46,7 @@ virtual void undo () {} virtual void redo () {} virtual ~HistoryEntry () {} + virtual HistoryType type () { return (HistoryType)(0); } }; // ============================================================================= @@ -133,6 +144,7 @@ void addEntry (HistoryEntry* entry); void undo (); void redo (); + void clear (); void updateActions (); };
--- a/ldforge.pro Wed Apr 10 16:17:22 2013 +0300 +++ b/ldforge.pro Wed Apr 10 19:26:14 2013 +0300 @@ -25,6 +25,7 @@ zz_addObjectDialog.h \ zz_colorSelectDialog.h \ zz_configDialog.h \ + zz_historyDialog.h \ zz_newPartDialog.h \ zz_setContentsDialog.h @@ -45,6 +46,7 @@ zz_addObjectDialog.cpp \ zz_colorSelectDialog.cpp \ zz_configDialog.cpp \ + zz_historyDialog.cpp \ zz_newPartDialog.cpp \ zz_setContentsDialog.cpp
--- a/ldtypes.cpp Wed Apr 10 16:17:22 2013 +0300 +++ b/ldtypes.cpp Wed Apr 10 19:26:14 2013 +0300 @@ -22,31 +22,32 @@ #include "misc.h" char const* g_saObjTypeNames[] = { - "unidentified", + "subfile", + "quadrilateral", + "triangle", + "line", + "condline", + "vertex", + "bfc", + "comment", "unknown", "empty", - "comment", - "subfile", - "line", - "triangle", - "quadrilateral", - "condline", - "bfc", - "vertex", + "unidentified", }; +// Should probably get rid of this array sometime char const* g_saObjTypeIcons[] = { - "error", + "subfile", + "quad", + "triangle", + "line", + "condline", + "vertex", + "bfc", + "comment", "error", "empty", - "comment", - "subfile", - "line", - "triangle", - "quad", - "condline", - "bfc", - "vertex", + "error", }; // ============================================================================= @@ -395,6 +396,9 @@ return -1; } +// ============================================================================= +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// ============================================================================= void LDObject::moveObjects (std::vector<LDObject*> objs, const bool bUp) { // If we move down, we need to iterate the array in reverse order. const long start = bUp ? 0 : (objs.size() - 1); @@ -419,4 +423,34 @@ obj->swap (g_CurrentFile->objects[lTarget]); } +} + +// ============================================================================= +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// ============================================================================= +str LDObject::objectListContents (std::vector<LDObject*>& objs) { + bool bFirstDetails = true; + str zText = ""; + + if (objs.size() == 0) + return "nothing"; // :) + + for (long i = 0; i < NUM_ObjectTypes; ++i) { + LDObjectType_e eType = (LDObjectType_e) i; + ulong ulCount = 0; + + for (LDObject* obj : objs) + if (obj->getType() == eType) + ulCount++; + + if (ulCount > 0) { + if (!bFirstDetails) + zText += ", "; + + zText.appendformat ("%lu %s%s", ulCount, g_saObjTypeNames[eType], PLURAL (ulCount)); + bFirstDetails = false; + } + } + + return zText; } \ No newline at end of file
--- a/ldtypes.h Wed Apr 10 16:17:22 2013 +0300 +++ b/ldtypes.h Wed Apr 10 19:26:14 2013 +0300 @@ -38,20 +38,21 @@ // ============================================================================= // LDObjectType_e // -// Object type codes +// Object type codes. Codes are sorted in order of significance. // ============================================================================= enum LDObjectType_e { - OBJ_Unidentified, // Object is an uninitialized (LDObject) (SHOULD NEVER HAPPEN) - OBJ_Gibberish, // Object is the result of failed parsing (LDGibberish) - OBJ_Empty, // Object represents an empty line (LDEmpty) - OBJ_Comment, // Object represents a comment (LDComment, code: 0) - OBJ_Subfile, // Object represents a sub-file reference (LDSubfile, code: 1) - OBJ_Line, // Object represents a line (LDLine, code: 2) - OBJ_Triangle, // Object represents a triangle (LDTriangle, code: 3) - OBJ_Quad, // Object represents a quadrilateral (LDQuad, code: 4) - OBJ_CondLine, // Object represents a conditional line (LDCondLine, code: 5) + OBJ_Subfile, // Object represents a sub-file reference + OBJ_Quad, // Object represents a quadrilateral + OBJ_Triangle, // Object represents a triangle + OBJ_Line, // Object represents a line + OBJ_CondLine, // Object represents a conditional line + OBJ_Vertex, // Object is a vertex, LDForge extension object OBJ_BFC, // Object represents a BFC statement - OBJ_Vertex // Object is a vertex, LDForge extension object (LDVertex) + OBJ_Comment, // Object represents a comment + OBJ_Gibberish, // Object is the result of failed parsing + OBJ_Empty, // Object represents an empty line + OBJ_Unidentified, // Object is an uninitialized (SHOULD NEVER HAPPEN) + NUM_ObjectTypes // Amount of object types }; // ============================================================================= @@ -99,6 +100,7 @@ void swap (LDObject* other); static void moveObjects (std::vector<LDObject*> objs, const bool bUp); + static str objectListContents (std::vector<LDObject*>& objs); QTreeWidgetItem* qObjListEntry; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zz_historyDialog.cpp Wed Apr 10 19:26:14 2013 +0300 @@ -0,0 +1,133 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013 Santeri `arezey` Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "zz_historyDialog.h" +#include "history.h" +#include <qboxlayout.h> +#include <qmessagebox.h> + +EXTERN_ACTION (undo); +EXTERN_ACTION (redo); + +// ============================================================================= +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// ============================================================================= +HistoryDialog::HistoryDialog (QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f) { + qHistoryList = new QListWidget; + qUndoButton = new QPushButton ("Undo"); + qRedoButton = new QPushButton ("Redo"); + qClearButton = new QPushButton ("Clear"); + qButtons = new QDialogButtonBox (QDialogButtonBox::Close); + + qUndoButton->setIcon (getIcon ("undo")); + qRedoButton->setIcon (getIcon ("redo")); + + connect (qUndoButton, SIGNAL (clicked ()), this, SLOT (slot_undo ())); + connect (qRedoButton, SIGNAL (clicked ()), this, SLOT (slot_redo ())); + connect (qClearButton, SIGNAL (clicked ()), this, SLOT (slot_clear ())); + connect (qButtons, SIGNAL (rejected ()), this, SLOT (reject ())); + + QVBoxLayout* qButtonLayout = new QVBoxLayout; + qButtonLayout->setDirection (QBoxLayout::TopToBottom); + qButtonLayout->addWidget (qUndoButton); + qButtonLayout->addWidget (qRedoButton); + qButtonLayout->addWidget (qClearButton); + qButtonLayout->addStretch (); + + QGridLayout* qLayout = new QGridLayout; + qLayout->addWidget (qHistoryList, 0, 0, 2, 1); + qLayout->addLayout (qButtonLayout, 0, 1); + qLayout->addWidget (qButtons, 1, 1); + + setLayout (qLayout); + setWindowIcon (getIcon ("history")); + setWindowTitle (APPNAME_DISPLAY " - Edit history"); + + populateList (); + updateButtons (); +} + +// ============================================================================= +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// ============================================================================= +void HistoryDialog::populateList () { + qHistoryList->clear (); + + for (HistoryEntry* entry : History::entries) { + str zText; + + switch (entry->type ()) { + case HISTORY_Addition: + { + AdditionHistory* addentry = static_cast<AdditionHistory*> (entry); + zText.format ("Added %s", LDObject::objectListContents (addentry->paObjs).chars()); + } + break; + + case HISTORY_QuadSplit: + { + QuadSplitHistory* splitentry = static_cast<QuadSplitHistory*> (entry); + ulong ulCount = splitentry->paQuads.size (); + zText.format ("Split %lu quad%s to triangles", ulCount, PLURAL (ulCount)); + break; + } + + default: + zText = "???"; + break; + } + + QListWidgetItem* qItem = new QListWidgetItem; + qItem->setText (zText); + qHistoryList->addItem (qItem); + } +} + +// ============================================================================= +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// ============================================================================= +void HistoryDialog::slot_undo () { + History::undo (); + updateButtons (); +} + +// ============================================================================= +void HistoryDialog::slot_redo () { + History::redo (); + updateButtons (); +} + +// ============================================================================= +void HistoryDialog::slot_clear () { + if (QMessageBox::question (this, "Confirm", "Are you sure you want to " + "clear the edit history?\nThis cannot be undone.", + (QMessageBox::Yes | QMessageBox::No), QMessageBox::No) != QMessageBox::Yes) + { + // Canceled + return; + } + + History::clear (); + populateList (); +} + +// ============================================================================= +void HistoryDialog::updateButtons () { + qUndoButton->setEnabled (ACTION_NAME (undo)->isEnabled ()); + qRedoButton->setEnabled (ACTION_NAME (redo)->isEnabled ()); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zz_historyDialog.h Wed Apr 10 19:26:14 2013 +0300 @@ -0,0 +1,48 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013 Santeri `arezey` Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ZZ_HISTORYDIALOG_H +#define ZZ_HISTORYDIALOG_H + +#include <qdialog.h> +#include <qdialogbuttonbox.h> +#include <qlistwidget.h> +#include <qpushbutton.h> +#include "gui.h" + +class HistoryDialog : public QDialog { + Q_OBJECT + +public: + explicit HistoryDialog (QWidget* parent = nullptr, Qt::WindowFlags f = 0); + void populateList (); + + QListWidget* qHistoryList; + QPushButton* qUndoButton, *qRedoButton, *qClearButton; + QDialogButtonBox* qButtons; + +private: + void updateButtons (); + +private slots: + void slot_undo (); + void slot_redo (); + void slot_clear (); +}; + +#endif // ZZ_HISTORYDIALOG_H \ No newline at end of file