# HG changeset patch # User Teemu Piippo # Date 1440899617 -10800 # Node ID a4b463a7ee82bd94026a543e5453766e20b5b7ee # Parent f81445a7abde9216bb86f56534e68406ab2d8dad Rename MainWindow files diff -r f81445a7abde -r a4b463a7ee82 CMakeLists.txt --- a/CMakeLists.txt Sun Aug 30 04:45:16 2015 +0300 +++ b/CMakeLists.txt Sun Aug 30 04:53:37 2015 +0300 @@ -52,7 +52,7 @@ src/ldObjectMath.cpp src/ldpaths.cpp src/main.cpp - src/mainWindow.cpp + src/mainwindow.cpp src/messageLog.cpp src/miscallenous.cpp src/partDownloader.cpp @@ -95,7 +95,7 @@ src/glRenderer.h src/glCompiler.h src/configuration.h - src/mainWindow.h + src/mainwindow.h src/editHistory.h src/format.h src/ldpaths.h @@ -124,13 +124,13 @@ ui/flip.ui ui/intersector.ui ui/isecalc.ui - ui/ldforge.ui ui/makeprim.ui ui/overlay.ui ui/rectifier.ui ui/replcoords.ui ui/rotpoint.ui ui/ytruder.ui + src/mainwindow.ui src/dialogs/colorselector.ui src/dialogs/ldrawpathdialog.ui src/dialogs/newpartdialog.ui diff -r f81445a7abde -r a4b463a7ee82 src/actions.cpp --- a/src/actions.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/actions.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -24,7 +24,7 @@ #include #include -#include "mainWindow.h" +#include "mainwindow.h" #include "ldDocument.h" #include "editHistory.h" #include "configDialog.h" diff -r f81445a7abde -r a4b463a7ee82 src/actionsEdit.cpp --- a/src/actionsEdit.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/actionsEdit.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -22,7 +22,7 @@ #include #include #include -#include "mainWindow.h" +#include "mainwindow.h" #include "main.h" #include "ldDocument.h" #include "dialogs/colorselector.h" diff -r f81445a7abde -r a4b463a7ee82 src/addObjectDialog.cpp --- a/src/addObjectDialog.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/addObjectDialog.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -25,7 +25,7 @@ #include #include #include -#include "mainWindow.h" +#include "mainwindow.h" #include "addObjectDialog.h" #include "ldDocument.h" #include "colors.h" diff -r f81445a7abde -r a4b463a7ee82 src/colors.cpp --- a/src/colors.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/colors.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -21,7 +21,7 @@ #include "colors.h" #include "ldDocument.h" #include "miscallenous.h" -#include "mainWindow.h" +#include "mainwindow.h" struct ColorDataEntry { diff -r f81445a7abde -r a4b463a7ee82 src/configDialog.h --- a/src/configDialog.h Sun Aug 30 04:45:16 2015 +0300 +++ b/src/configDialog.h Sun Aug 30 04:53:37 2015 +0300 @@ -17,7 +17,7 @@ */ #pragma once -#include "mainWindow.h" +#include "mainwindow.h" #include class Ui_ConfigUI; diff -r f81445a7abde -r a4b463a7ee82 src/configuration.cpp --- a/src/configuration.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/configuration.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -29,7 +29,7 @@ #include "main.h" #include "configuration.h" #include "miscallenous.h" -#include "mainWindow.h" +#include "mainwindow.h" #include "ldDocument.h" #include "glRenderer.h" #include "configuration.inc" diff -r f81445a7abde -r a4b463a7ee82 src/dialogs.cpp --- a/src/dialogs.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/dialogs.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -32,7 +32,7 @@ #include #include "dialogs.h" #include "radioGroup.h" -#include "mainWindow.h" +#include "mainwindow.h" #include "glRenderer.h" #include "documentation.h" #include "ldDocument.h" diff -r f81445a7abde -r a4b463a7ee82 src/dialogs/colorselector.cpp --- a/src/dialogs/colorselector.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/dialogs/colorselector.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -22,7 +22,7 @@ #include #include #include "../main.h" -#include "../mainWindow.h" +#include "../mainwindow.h" #include "../colors.h" #include "../configuration.h" #include "../miscallenous.h" diff -r f81445a7abde -r a4b463a7ee82 src/dialogs/ldrawpathdialog.cpp --- a/src/dialogs/ldrawpathdialog.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/dialogs/ldrawpathdialog.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -21,7 +21,7 @@ #include #include "ldrawpathdialog.h" #include "ui_ldrawpathdialog.h" -#include "../mainWindow.h" +#include "../mainwindow.h" LDrawPathDialog::LDrawPathDialog (const QString& defaultPath, bool validDefault, QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f), diff -r f81445a7abde -r a4b463a7ee82 src/editHistory.cpp --- a/src/editHistory.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/editHistory.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -20,7 +20,7 @@ #include "ldObject.h" #include "ldDocument.h" #include "miscallenous.h" -#include "mainWindow.h" +#include "mainwindow.h" #include "glRenderer.h" // ============================================================================= diff -r f81445a7abde -r a4b463a7ee82 src/editmodes/abstractEditMode.cpp --- a/src/editmodes/abstractEditMode.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/editmodes/abstractEditMode.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -25,7 +25,7 @@ #include "circleMode.h" #include "magicWandMode.h" #include "linePathMode.h" -#include "../mainWindow.h" +#include "../mainwindow.h" #include "../glRenderer.h" CFGENTRY (Bool, DrawLineLengths, true) diff -r f81445a7abde -r a4b463a7ee82 src/editmodes/circleMode.cpp --- a/src/editmodes/circleMode.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/editmodes/circleMode.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -24,7 +24,7 @@ #include "../ringFinder.h" #include "../primitives.h" #include "../glRenderer.h" -#include "../mainWindow.h" +#include "../mainwindow.h" #include "../ldObjectMath.h" CircleMode::CircleMode (GLRenderer* renderer) : diff -r f81445a7abde -r a4b463a7ee82 src/editmodes/linePathMode.cpp --- a/src/editmodes/linePathMode.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/editmodes/linePathMode.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -1,6 +1,6 @@ #include "linePathMode.h" #include "../glRenderer.h" -#include "../mainWindow.h" +#include "../mainwindow.h" #include LinePathMode::LinePathMode (GLRenderer *renderer) : diff -r f81445a7abde -r a4b463a7ee82 src/editmodes/magicWandMode.cpp --- a/src/editmodes/magicWandMode.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/editmodes/magicWandMode.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -19,7 +19,7 @@ #include #include "magicWandMode.h" #include "../ldDocument.h" -#include "../mainWindow.h" +#include "../mainwindow.h" #include "../glRenderer.h" MagicWandMode::MagicWandMode (GLRenderer* renderer) : diff -r f81445a7abde -r a4b463a7ee82 src/editmodes/selectMode.cpp --- a/src/editmodes/selectMode.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/editmodes/selectMode.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -20,7 +20,7 @@ #include "selectMode.h" #include "../glRenderer.h" #include "../addObjectDialog.h" -#include "../mainWindow.h" +#include "../mainwindow.h" #include "../glRenderer.h" SelectMode::SelectMode (GLRenderer* renderer) : diff -r f81445a7abde -r a4b463a7ee82 src/extPrograms.cpp --- a/src/extPrograms.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/extPrograms.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -28,7 +28,7 @@ #include "main.h" #include "configuration.h" #include "miscallenous.h" -#include "mainWindow.h" +#include "mainwindow.h" #include "ldDocument.h" #include "radioGroup.h" #include "editHistory.h" diff -r f81445a7abde -r a4b463a7ee82 src/glRenderer.cpp --- a/src/glRenderer.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/glRenderer.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -33,7 +33,7 @@ #include "ldDocument.h" #include "glRenderer.h" #include "colors.h" -#include "mainWindow.h" +#include "mainwindow.h" #include "miscallenous.h" #include "editHistory.h" #include "dialogs.h" diff -r f81445a7abde -r a4b463a7ee82 src/ldDocument.cpp --- a/src/ldDocument.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/ldDocument.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -25,7 +25,7 @@ #include "configuration.h" #include "ldDocument.h" #include "miscallenous.h" -#include "mainWindow.h" +#include "mainwindow.h" #include "editHistory.h" #include "glRenderer.h" #include "glCompiler.h" diff -r f81445a7abde -r a4b463a7ee82 src/ldObject.cpp --- a/src/ldObject.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/ldObject.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -21,7 +21,7 @@ #include "ldObject.h" #include "ldDocument.h" #include "miscallenous.h" -#include "mainWindow.h" +#include "mainwindow.h" #include "editHistory.h" #include "glRenderer.h" #include "colors.h" diff -r f81445a7abde -r a4b463a7ee82 src/main.cpp --- a/src/main.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/main.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -22,7 +22,7 @@ #include #include #include -#include "mainWindow.h" +#include "mainwindow.h" #include "ldDocument.h" #include "miscallenous.h" #include "configuration.h" diff -r f81445a7abde -r a4b463a7ee82 src/mainWindow.cpp --- a/src/mainWindow.cpp Sun Aug 30 04:45:16 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1190 +0,0 @@ -/* - * LDForge: LDraw parts authoring CAD - * Copyright (C) 2013, 2014 Teemu 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "main.h" -#include "glRenderer.h" -#include "mainWindow.h" -#include "ldDocument.h" -#include "configuration.h" -#include "miscallenous.h" -#include "colors.h" -#include "editHistory.h" -#include "radioGroup.h" -#include "addObjectDialog.h" -#include "messageLog.h" -#include "configuration.h" -#include "ui_ldforge.h" -#include "primitives.h" -#include "editmodes/abstractEditMode.h" - -static bool g_isSelectionLocked = false; -static QMap g_defaultShortcuts; - -CFGENTRY (Bool, ColorizeObjectsList, true) -CFGENTRY (String, QuickColorToolbar, "4:25:14:27:2:3:11:1:22:|:0:72:71:15") -CFGENTRY (Bool, ListImplicitFiles, false) -CFGENTRY (List, HiddenToolbars, {}) -EXTERN_CFGENTRY (List, RecentFiles) -EXTERN_CFGENTRY (Bool, DrawAxes) -EXTERN_CFGENTRY (String, MainColor) -EXTERN_CFGENTRY (Float, MainColorAlpha) -EXTERN_CFGENTRY (Bool, DrawWireframe) -EXTERN_CFGENTRY (Bool, BFCRedGreenView) -EXTERN_CFGENTRY (Bool, DrawAngles) -EXTERN_CFGENTRY (Bool, RandomColors) -EXTERN_CFGENTRY (Bool, DrawSurfaces) -EXTERN_CFGENTRY (Bool, DrawEdgeLines) -EXTERN_CFGENTRY (Bool, DrawConditionalLines) - -// ============================================================================= -// -MainWindow::MainWindow (QWidget* parent, Qt::WindowFlags flags) : - QMainWindow (parent, flags) -{ - g_win = this; - ui = new Ui_LDForgeUI; - ui->setupUi (this); - m_updatingTabs = false; - m_renderer = new GLRenderer (this); - m_tabs = new QTabBar; - m_tabs->setTabsClosable (true); - ui->verticalLayout->insertWidget (0, m_tabs); - - // Stuff the renderer into its frame - QVBoxLayout* rendererLayout = new QVBoxLayout (ui->rendererFrame); - rendererLayout->addWidget (R()); - - connect (ui->objectList, SIGNAL (itemSelectionChanged()), this, SLOT (slot_selectionChanged())); - connect (ui->objectList, SIGNAL (itemDoubleClicked (QListWidgetItem*)), this, SLOT (slot_editObject (QListWidgetItem*))); - connect (m_tabs, SIGNAL (currentChanged(int)), this, SLOT (changeCurrentFile())); - connect (m_tabs, SIGNAL (tabCloseRequested (int)), this, SLOT (closeTab (int))); - - if (ActivePrimitiveScanner() != null) - connect (ActivePrimitiveScanner(), SIGNAL (workDone()), this, SLOT (updatePrimitives())); - else - updatePrimitives(); - - m_msglog = new MessageManager; - m_msglog->setRenderer (R()); - m_renderer->setMessageLog (m_msglog); - m_quickColors = LoadQuickColorList(); - slot_selectionChanged(); - setStatusBar (new QStatusBar); - updateActions(); - - // Connect all actions and save default sequences - applyToActions ([&](QAction* act) - { - connect (act, SIGNAL (triggered()), this, SLOT (slot_action())); - g_defaultShortcuts[act] = act->shortcut(); - }); - - updateGridToolBar(); - updateEditModeActions(); - updateRecentFilesMenu(); - updateColorToolbar(); - updateTitle(); - loadShortcuts (Config::SettingsObject()); - setMinimumSize (300, 200); - connect (qApp, SIGNAL (aboutToQuit()), this, SLOT (slot_lastSecondCleanup())); - connect (ui->ringToolHiRes, SIGNAL (clicked (bool)), this, SLOT (ringToolHiResClicked (bool))); - connect (ui->ringToolSegments, SIGNAL (valueChanged (int)), - this, SLOT (circleToolSegmentsChanged())); - circleToolSegmentsChanged(); // invoke it manually for initial label text - - for (QVariant const& toolbarname : cfg::HiddenToolbars) - { - QToolBar* toolbar = findChild (toolbarname.toString()); - - if (toolbar != null) - toolbar->hide(); - } -} - -MainWindow::~MainWindow() -{ - g_win = null; -} - -// ============================================================================= -// -void MainWindow::slot_action() -{ - // Get the name of the sender object and use it to compose the slot name, - // then invoke this slot to call the action. - QMetaObject::invokeMethod (this, - qPrintable (format ("slot_%1", sender()->objectName())), Qt::DirectConnection); - endAction(); -} - -// ============================================================================= -// -void MainWindow::endAction() -{ - // Add a step in the history now. - CurrentDocument()->addHistoryStep(); - - // Update the list item of the current file - we may need to draw an icon - // now that marks it as having unsaved changes. - updateDocumentListItem (CurrentDocument()); - refresh(); -} - -// ============================================================================= -// -void MainWindow::slot_lastSecondCleanup() -{ - delete m_renderer; - delete ui; -} - -// ============================================================================= -// -void MainWindow::updateRecentFilesMenu() -{ - // First, clear any items in the recent files menu -for (QAction * recent : m_recentFiles) - delete recent; - - m_recentFiles.clear(); - - QAction* first = null; - - for (const QVariant& it : cfg::RecentFiles) - { - QString file = it.toString(); - QAction* recent = new QAction (GetIcon ("open-recent"), file, this); - - connect (recent, SIGNAL (triggered()), this, SLOT (slot_recentFile())); - ui->menuOpenRecent->insertAction (first, recent); - m_recentFiles << recent; - first = recent; - } -} - -// ============================================================================= -// -QList LoadQuickColorList() -{ - QList colors; - - for (QString colorname : cfg::QuickColorToolbar.split (":")) - { - if (colorname == "|") - colors << LDQuickColor::getSeparator(); - else - { - LDColor color = colorname.toInt(); - - if (color.isValid()) - colors << LDQuickColor (color, null); - } - } - - return colors; -} - -// ============================================================================= -// -void MainWindow::updateColorToolbar() -{ - m_colorButtons.clear(); - ui->toolBarColors->clear(); - ui->toolBarColors->addAction (ui->actionUncolor); - ui->toolBarColors->addSeparator(); - - for (LDQuickColor& entry : m_quickColors) - { - if (entry.isSeparator()) - { - ui->toolBarColors->addSeparator(); - } - else - { - QToolButton* colorButton = new QToolButton; - colorButton->setIcon (MakeColorIcon (entry.color(), 16)); - colorButton->setIconSize (QSize (16, 16)); - colorButton->setToolTip (entry.color().name()); - - connect (colorButton, SIGNAL (clicked()), this, SLOT (slot_quickColor())); - ui->toolBarColors->addWidget (colorButton); - m_colorButtons << colorButton; - - entry.setToolButton (colorButton); - } - } - - updateGridToolBar(); -} - -// ============================================================================= -// -void MainWindow::updateGridToolBar() -{ - // Ensure that the current grid - and only the current grid - is selected. - ui->actionGridCoarse->setChecked (cfg::Grid == Grid::Coarse); - ui->actionGridMedium->setChecked (cfg::Grid == Grid::Medium); - ui->actionGridFine->setChecked (cfg::Grid == Grid::Fine); -} - -// ============================================================================= -// -void MainWindow::updateTitle() -{ - QString title = format (APPNAME " " VERSION_STRING); - - // Append our current file if we have one - if (CurrentDocument()) - { - title += ": "; - title += CurrentDocument()->getDisplayName(); - - if (CurrentDocument()->getObjectCount() > 0 and - CurrentDocument()->getObject (0)->type() == OBJ_Comment) - { - // Append title - LDComment* comm = static_cast (CurrentDocument()->getObject (0)); - title += format (": %1", comm->text()); - } - - if (CurrentDocument()->hasUnsavedChanges()) - title += '*'; - } - -#ifdef DEBUG - title += " [debug build]"; -#elif BUILD_ID != BUILD_RELEASE - title += " [pre-release build]"; -#endif // DEBUG - - if (strlen (commitTimeString())) - title += format (" (%1)", QString::fromUtf8 (commitTimeString())); - - setWindowTitle (title); -} - -// ============================================================================= -// -int MainWindow::deleteSelection() -{ - if (Selection().isEmpty()) - return 0; - - LDObjectList selCopy = Selection(); - - // Delete the objects that were being selected - for (LDObject* obj : selCopy) - obj->destroy(); - - refresh(); - return selCopy.size(); -} - -// ============================================================================= -// -void MainWindow::buildObjList() -{ - if (not CurrentDocument()) - return; - - // Lock the selection while we do this so that refreshing the object list - // doesn't trigger selection updating so that the selection doesn't get lost - // while this is done. - g_isSelectionLocked = true; - - for (int i = 0; i < ui->objectList->count(); ++i) - delete ui->objectList->item (i); - - ui->objectList->clear(); - - for (LDObject* obj : CurrentDocument()->objects()) - { - QString descr; - - switch (obj->type()) - { - case OBJ_Comment: - { - descr = static_cast (obj)->text(); - - // Remove leading whitespace - while (descr[0] == ' ') - descr.remove (0, 1); - - break; - } - - case OBJ_Empty: - break; // leave it empty - - case OBJ_Line: - case OBJ_Triangle: - case OBJ_Quad: - case OBJ_CondLine: - { - for (int i = 0; i < obj->numVertices(); ++i) - { - if (i != 0) - descr += ", "; - - descr += obj->vertex (i).toString (true); - } - break; - } - - case OBJ_Error: - { - descr = format ("ERROR: %1", obj->asText()); - break; - } - - case OBJ_Subfile: - { - LDSubfile* ref = static_cast (obj); - - descr = format ("%1 %2, (", ref->fileInfo()->getDisplayName(), ref->position().toString (true)); - - for (int i = 0; i < 9; ++i) - descr += format ("%1%2", ref->transform()[i], (i != 8) ? " " : ""); - - descr += ')'; - break; - } - - case OBJ_BFC: - { - descr = LDBFC::StatementStrings[int (static_cast (obj)->statement())]; - break; - } - - case OBJ_Overlay: - { - LDOverlay* ovl = static_cast (obj); - descr = format ("[%1] %2 (%3, %4), %5 x %6", g_CameraNames[ovl->camera()], - Basename (ovl->fileName()), ovl->x(), ovl->y(), - ovl->width(), ovl->height()); - break; - } - - default: - { - descr = obj->typeName(); - break; - } - } - - QListWidgetItem* item = new QListWidgetItem (descr); - item->setIcon (GetIcon (obj->typeName())); - - // Use italic font if hidden - if (obj->isHidden()) - { - QFont font = item->font(); - font.setItalic (true); - item->setFont (font); - } - - // Color gibberish orange on red so it stands out. - if (obj->type() == OBJ_Error) - { - item->setBackground (QColor ("#AA0000")); - item->setForeground (QColor ("#FFAA00")); - } - else if (cfg::ColorizeObjectsList and obj->isColored() and - obj->color().isValid() and obj->color() != MainColor and obj->color() != EdgeColor) - { - // If the object isn't in the main or edge color, draw this list entry in that color. - item->setForeground (obj->color().faceColor()); - } - - obj->qObjListEntry = item; - ui->objectList->insertItem (ui->objectList->count(), item); - } - - g_isSelectionLocked = false; - updateSelection(); - scrollToSelection(); -} - -// ============================================================================= -// -void MainWindow::scrollToSelection() -{ - if (Selection().isEmpty()) - return; - - LDObject* obj = Selection().last(); - ui->objectList->scrollToItem (obj->qObjListEntry); -} - -// ============================================================================= -// -void MainWindow::slot_selectionChanged() -{ - if (g_isSelectionLocked == true or CurrentDocument() == null) - return; - - LDObjectList priorSelection = Selection(); - - // Get the objects from the object list selection - CurrentDocument()->clearSelection(); - const QList items = ui->objectList->selectedItems(); - - for (LDObject* obj : CurrentDocument()->objects()) - { - for (QListWidgetItem* item : items) - { - if (item == obj->qObjListEntry) - { - obj->select(); - break; - } - } - } - - // The select() method calls may have selected additional items (i.e. invertnexts) - // Update it all now. - updateSelection(); - - // Update the GL renderer - LDObjectList compound = priorSelection + Selection(); - RemoveDuplicates (compound); - - for (LDObject* obj : compound) - R()->compileObject (obj); - - R()->update(); -} - -// ============================================================================= -// -void MainWindow::slot_recentFile() -{ - QAction* qAct = static_cast (sender()); - OpenMainModel (qAct->text()); -} - -// ============================================================================= -// -void MainWindow::slot_quickColor() -{ - QToolButton* button = static_cast (sender()); - LDColor color = LDColor::nullColor(); - - for (const LDQuickColor& entry : m_quickColors) - { - if (entry.toolButton() == button) - { - color = entry.color(); - break; - } - } - - if (not color.isValid()) - return; - - for (LDObject* obj : Selection()) - { - if (not obj->isColored()) - continue; // uncolored object - - obj->setColor (color); - R()->compileObject (obj); - } - - endAction(); - refresh(); -} - -// ============================================================================= -// -int MainWindow::getInsertionPoint() -{ - // If we have a selection, put the item after it. - if (not Selection().isEmpty()) - return Selection().last()->lineNumber() + 1; - - // Otherwise place the object at the end. - return CurrentDocument()->getObjectCount(); -} - -// ============================================================================= -// -void MainWindow::doFullRefresh() -{ - buildObjList(); - m_renderer->hardRefresh(); -} - -// ============================================================================= -// -void MainWindow::refresh() -{ - buildObjList(); - m_renderer->update(); -} - -// ============================================================================= -// -void MainWindow::updateSelection() -{ - g_isSelectionLocked = true; - QItemSelection itemselect; - int top = -1; - int bottom = -1; - - for (LDObject* obj : Selection()) - { - if (obj->qObjListEntry == null) - continue; - - int row = ui->objectList->row (obj->qObjListEntry); - - if (top == -1) - { - top = bottom = row; - } - else - { - if (row != bottom + 1) - { - itemselect.select (ui->objectList->model()->index (top, 0), - ui->objectList->model()->index (bottom, 0)); - top = -1; - } - - bottom = row; - } - } - - if (top != -1) - { - itemselect.select (ui->objectList->model()->index (top, 0), - ui->objectList->model()->index (bottom, 0)); - } - - ui->objectList->selectionModel()->select (itemselect, QItemSelectionModel::ClearAndSelect); - g_isSelectionLocked = false; -} - -// ============================================================================= -// -LDColor MainWindow::getSelectedColor() -{ - LDColor result; - - for (LDObject* obj : Selection()) - { - if (not obj->isColored()) - continue; // This one doesn't use color so it doesn't have a say - - if (result.isValid() and obj->color() != result) - return LDColor::nullColor(); // No consensus in object color - - if (not result.isValid()) - result = obj->color(); - } - - return result; -} - -// ============================================================================= -// -void MainWindow::closeEvent (QCloseEvent* ev) -{ - // Check whether it's safe to close all files. - if (not IsSafeToCloseAll()) - { - ev->ignore(); - return; - } - - // Save the toolbar set - cfg::HiddenToolbars.clear(); - - for (QToolBar* toolbar : findChildren()) - { - if (toolbar->isHidden()) - cfg::HiddenToolbars << toolbar->objectName(); - } - - // Save the configuration before leaving. - Config::Save(); - ev->accept(); -} - -// ============================================================================= -// -void MainWindow::spawnContextMenu (const QPoint pos) -{ - const bool single = (Selection().size() == 1); - LDObject* singleObj = single ? Selection().first() : nullptr; - - bool hasSubfiles = false; - - for (LDObject* obj : Selection()) - { - if (obj->type() == OBJ_Subfile) - { - hasSubfiles = true; - break; - } - } - - QMenu* contextMenu = new QMenu; - - if (single and singleObj->type() != OBJ_Empty) - { - contextMenu->addAction (ui->actionEdit); - contextMenu->addSeparator(); - } - - contextMenu->addAction (ui->actionCut); - contextMenu->addAction (ui->actionCopy); - contextMenu->addAction (ui->actionPaste); - contextMenu->addAction (ui->actionDelete); - contextMenu->addSeparator(); - contextMenu->addAction (ui->actionSetColor); - - if (single) - contextMenu->addAction (ui->actionEditRaw); - - contextMenu->addAction (ui->actionBorders); - contextMenu->addAction (ui->actionSetOverlay); - contextMenu->addAction (ui->actionClearOverlay); - - if (hasSubfiles) - { - contextMenu->addSeparator(); - contextMenu->addAction (ui->actionOpenSubfiles); - } - - contextMenu->addSeparator(); - contextMenu->addAction (ui->actionModeSelect); - contextMenu->addAction (ui->actionModeDraw); - contextMenu->addAction (ui->actionModeCircle); - - if (not Selection().isEmpty()) - { - contextMenu->addSeparator(); - contextMenu->addAction (ui->actionSubfileSelection); - } - - if (R()->camera() != EFreeCamera) - { - contextMenu->addSeparator(); - contextMenu->addAction (ui->actionSetDrawDepth); - } - - contextMenu->exec (pos); -} - -// ============================================================================= -// -void MainWindow::deleteByColor (LDColor color) -{ - LDObjectList objs; - - for (LDObject* obj : CurrentDocument()->objects()) - { - if (not obj->isColored() or obj->color() != color) - continue; - - objs << obj; - } - - for (LDObject* obj : objs) - obj->destroy(); -} - -// ============================================================================= -// -void MainWindow::updateEditModeActions() -{ - const EditModeType mode = R()->currentEditModeType(); - ui->actionModeSelect->setChecked (mode == EditModeType::Select); - ui->actionModeDraw->setChecked (mode == EditModeType::Draw); - ui->actionModeRectangle->setChecked (mode == EditModeType::Rectangle); - ui->actionModeCircle->setChecked (mode == EditModeType::Circle); - ui->actionModeMagicWand->setChecked (mode == EditModeType::MagicWand); - ui->actionModeLinePath->setChecked (mode == EditModeType::LinePath); -} - -// ============================================================================= -// -void MainWindow::slot_editObject (QListWidgetItem* listitem) -{ - for (LDObject* it : CurrentDocument()->objects()) - { - if (it->qObjListEntry == listitem) - { - AddObjectDialog::staticDialog (it->type(), it); - break; - } - } -} - -// ============================================================================= -// -bool MainWindow::save (LDDocument* doc, bool saveAs) -{ - QString path = doc->fullPath(); - int64 savesize; - - if (saveAs or path.isEmpty()) - { - QString name = doc->defaultName(); - - if (not doc->fullPath().isEmpty()) - name = doc->fullPath(); - elif (not doc->name().isEmpty()) - name = doc->name(); - - name.replace ("\\", "/"); - path = QFileDialog::getSaveFileName (g_win, tr ("Save As"), - name, tr ("LDraw files (*.dat *.ldr)")); - - if (path.isEmpty()) - { - // User didn't give a file name, abort. - return false; - } - } - - if (doc->save (path, &savesize)) - { - if (doc == CurrentDocument()) - updateTitle(); - - print ("Saved to %1 (%2)", path, MakePrettyFileSize (savesize)); - - // Add it to recent files - AddRecentFile (path); - return true; - } - - QString message = format (tr ("Failed to save to %1: %2"), path, strerror (errno)); - - // Tell the user the save failed, and give the option for saving as with it. - QMessageBox dlg (QMessageBox::Critical, tr ("Save Failure"), message, QMessageBox::Close, g_win); - - // Add a save-as button - QPushButton* saveAsBtn = new QPushButton (tr ("Save As")); - saveAsBtn->setIcon (GetIcon ("file-save-as")); - dlg.addButton (saveAsBtn, QMessageBox::ActionRole); - dlg.setDefaultButton (QMessageBox::Close); - dlg.exec(); - - if (dlg.clickedButton() == saveAsBtn) - return save (doc, true); // yay recursion! - - return false; -} - -void MainWindow::addMessage (QString msg) -{ - m_msglog->addLine (msg); -} - -// ============================================================================ -void ObjectList::contextMenuEvent (QContextMenuEvent* ev) -{ - g_win->spawnContextMenu (ev->globalPos()); -} - -// ============================================================================= -// -QPixmap GetIcon (QString iconName) -{ - return (QPixmap (format (":/icons/%1.png", iconName))); -} - -// ============================================================================= -// -bool Confirm (const QString& message) -{ - return Confirm (MainWindow::tr ("Confirm"), message); -} - -// ============================================================================= -// -bool Confirm (const QString& title, const QString& message) -{ - return QMessageBox::question (g_win, title, message, - (QMessageBox::Yes | QMessageBox::No), QMessageBox::No) == QMessageBox::Yes; -} - -// ============================================================================= -// -void Critical (const QString& message) -{ - QMessageBox::critical (g_win, MainWindow::tr ("Error"), message, - (QMessageBox::Close), QMessageBox::Close); -} - -// ============================================================================= -// -QIcon MakeColorIcon (LDColor colinfo, const int size) -{ - // Create an image object and link a painter to it. - QImage img (size, size, QImage::Format_ARGB32); - QPainter paint (&img); - QColor col = colinfo.faceColor(); - - if (colinfo == MainColor) - { - // Use the user preferences for main color here - col = cfg::MainColor; - col.setAlphaF (cfg::MainColorAlpha); - } - - // Paint the icon border - paint.fillRect (QRect (0, 0, size, size), colinfo.edgeColor()); - - // Paint the checkerboard background, visible with translucent icons - paint.drawPixmap (QRect (1, 1, size - 2, size - 2), GetIcon ("checkerboard"), QRect (0, 0, 8, 8)); - - // Paint the color above the checkerboard - paint.fillRect (QRect (1, 1, size - 2, size - 2), col); - return QIcon (QPixmap::fromImage (img)); -} - -// ============================================================================= -// -void MakeColorComboBox (QComboBox* box) -{ - std::map counts; - - for (LDObject* obj : CurrentDocument()->objects()) - { - if (not obj->isColored() or not obj->color().isValid()) - continue; - - if (counts.find (obj->color()) == counts.end()) - counts[obj->color()] = 1; - else - counts[obj->color()]++; - } - - box->clear(); - int row = 0; - - for (const auto& pair : counts) - { - QIcon ico = MakeColorIcon (pair.first, 16); - box->addItem (ico, format ("[%1] %2 (%3 object%4)", - pair.first, pair.first.name(), pair.second, Plural (pair.second))); - box->setItemData (row, pair.first.index()); - - ++row; - } -} - -// ============================================================================= -// -void MainWindow::updateDocumentList() -{ - m_updatingTabs = true; - - while (m_tabs->count() > 0) - m_tabs->removeTab (0); - - for (LDDocument* f : LDDocument::explicitDocuments()) - { - // Add an item to the list for this file and store the tab index - // in the document so we can find documents by tab index. - f->setTabIndex (m_tabs->addTab ("")); - updateDocumentListItem (f); - } - - m_updatingTabs = false; -} - -// ============================================================================= -// -void MainWindow::updateDocumentListItem (LDDocument* doc) -{ - bool oldUpdatingTabs = m_updatingTabs; - m_updatingTabs = true; - - if (doc->tabIndex() == -1) - { - // We don't have a list item for this file, so the list either doesn't - // exist yet or is out of date. Build the list now. - updateDocumentList(); - return; - } - - // If this is the current file, it also needs to be the selected item on - // the list. - if (doc == CurrentDocument()) - m_tabs->setCurrentIndex (doc->tabIndex()); - - m_tabs->setTabText (doc->tabIndex(), doc->getDisplayName()); - - // If the document.has unsaved changes, draw a little icon next to it to mark that. - m_tabs->setTabIcon (doc->tabIndex(), doc->hasUnsavedChanges() ? GetIcon ("file-save") : QIcon()); - m_tabs->setTabData (doc->tabIndex(), doc->name()); - m_updatingTabs = oldUpdatingTabs; -} - -// ============================================================================= -// -// A file is selected from the list of files on the left of the screen. Find out -// which file was picked and change to it. -// -void MainWindow::changeCurrentFile() -{ - if (m_updatingTabs) - return; - - LDDocument* file = nullptr; - int tabIndex = m_tabs->currentIndex(); - - // Find the file pointer of the item that was selected. - for (LDDocument* it : LDDocument::explicitDocuments()) - { - if (it->tabIndex() == tabIndex) - { - file = it; - break; - } - } - - // If we picked the same file we're currently on, we don't need to do - // anything. - if (file == null or file == CurrentDocument()) - return; - - LDDocument::setCurrent (file); -} - -// ============================================================================= -// -void MainWindow::refreshObjectList() -{ -#if 0 - ui->objectList->clear(); - LDDocument* f = getCurrentDocument(); - -for (LDObject* obj : *f) - ui->objectList->addItem (obj->qObjListEntry); - -#endif - - buildObjList(); -} - -// ============================================================================= -// -void MainWindow::updateActions() -{ - if (CurrentDocument() != null and CurrentDocument()->history() != null) - { - History* his = CurrentDocument()->history(); - int pos = his->position(); - ui->actionUndo->setEnabled (pos != -1); - ui->actionRedo->setEnabled (pos < (long) his->getSize() - 1); - } - - ui->actionWireframe->setChecked (cfg::DrawWireframe); - ui->actionAxes->setChecked (cfg::DrawAxes); - ui->actionBFCView->setChecked (cfg::BFCRedGreenView); - ui->actionRandomColors->setChecked (cfg::RandomColors); - ui->actionDrawAngles->setChecked (cfg::DrawAngles); - ui->actionDrawSurfaces->setChecked (cfg::DrawSurfaces); - ui->actionDrawEdgeLines->setChecked (cfg::DrawEdgeLines); - ui->actionDrawConditionalLines->setChecked (cfg::DrawConditionalLines); -} - -// ============================================================================= -// -void MainWindow::updatePrimitives() -{ - PopulatePrimitives (ui->primitives); -} - -// ============================================================================= -// -void MainWindow::closeTab (int tabindex) -{ - LDDocument* doc = FindDocument (m_tabs->tabData (tabindex).toString()); - - if (doc == null) - return; - - doc->dismiss(); -} - -// ============================================================================= -// -void MainWindow::loadShortcuts (QSettings const* settings) -{ - for (QAction* act : findChildren()) - { - QKeySequence seq = settings->value ("shortcut_" + act->objectName(), act->shortcut()).value(); - act->setShortcut (seq); - } -} - -// ============================================================================= -// -void MainWindow::saveShortcuts (QSettings* settings) -{ - applyToActions ([&](QAction* act) - { - QString const key = "shortcut_" + act->objectName(); - - if (g_defaultShortcuts[act] != act->shortcut()) - settings->setValue (key, act->shortcut()); - else - settings->remove (key); - }); -} - -// ============================================================================= -// -void MainWindow::applyToActions (std::function function) -{ - for (QAction* act : findChildren()) - { - if (not act->objectName().isEmpty()) - function (act); - } -} - -// ============================================================================= -// -QKeySequence MainWindow::defaultShortcut (QAction* act) // [static] -{ - return g_defaultShortcuts[act]; -} - -// ============================================================================= -// -bool MainWindow::ringToolHiRes() const -{ - return ui->ringToolHiRes->isChecked(); -} - -// ============================================================================= -// -int MainWindow::ringToolSegments() const -{ - return ui->ringToolSegments->value(); -} - -// ============================================================================= -// -void MainWindow::ringToolHiResClicked (bool checked) -{ - if (checked) - { - ui->ringToolSegments->setMaximum (HighResolution); - ui->ringToolSegments->setValue (ui->ringToolSegments->value() * 3); - } - else - { - ui->ringToolSegments->setValue (ui->ringToolSegments->value() / 3); - ui->ringToolSegments->setMaximum (LowResolution); - } -} - -// ============================================================================= -// -void MainWindow::circleToolSegmentsChanged() -{ - int numerator (ui->ringToolSegments->value()); - int denominator (ui->ringToolHiRes->isChecked() ? HighResolution : LowResolution); - Simplify (numerator, denominator); - ui->ringToolSegmentsLabel->setText (format ("%1 / %2", numerator, denominator)); -} - -// ============================================================================= -// -QImage GetImageFromScreencap (uchar* data, int w, int h) -{ - // GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well. - return QImage (data, w, h, QImage::Format_ARGB32).rgbSwapped().mirrored(); -} - -// ============================================================================= -// -LDQuickColor::LDQuickColor (LDColor color, QToolButton* toolButton) : - m_color (color), - m_toolButton (toolButton) {} - -// ============================================================================= -// -LDQuickColor LDQuickColor::getSeparator() -{ - return LDQuickColor (LDColor::nullColor(), null); -} - -// ============================================================================= -// -bool LDQuickColor::isSeparator() const -{ - return color() == LDColor::nullColor(); -} - -void PopulatePrimitives (QTreeWidget* tw, QString const& selectByDefault) -{ - tw->clear(); - - for (PrimitiveCategory* cat : g_PrimitiveCategories) - { - SubfileListItem* parentItem = new SubfileListItem (tw, null); - parentItem->setText (0, cat->name()); - QList subfileItems; - - for (Primitive& prim : cat->prims) - { - SubfileListItem* item = new SubfileListItem (parentItem, &prim); - item->setText (0, format ("%1 - %2", prim.name, prim.title)); - subfileItems << item; - - // If this primitive is the one the current object points to, - // select it by default - if (selectByDefault == prim.name) - tw->setCurrentItem (item); - } - - tw->addTopLevelItem (parentItem); - } -} diff -r f81445a7abde -r a4b463a7ee82 src/mainWindow.h --- a/src/mainWindow.h Sun Aug 30 04:45:16 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,391 +0,0 @@ -/* - * LDForge: LDraw parts authoring CAD - * Copyright (C) 2013, 2014 Teemu 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 . - */ - -#pragma once -#include -#include -#include -#include -#include -#include "configuration.h" -#include "ldObject.h" -#include "ui_ldforge.h" -#include "colors.h" - -class MessageManager; -class MainWindow; -class QToolButton; -class QDialogButtonBox; -class GLRenderer; -class QComboBox; -class QProgressBar; -class Ui_LDForgeUI; -struct Primitive; - -// Stuff for dialogs -#define IMPLEMENT_DIALOG_BUTTONS \ - bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel); \ - connect (bbx_buttons, SIGNAL (accepted()), this, SLOT (accept())); \ - connect (bbx_buttons, SIGNAL (rejected()), this, SLOT (reject())); \ - -class LDQuickColor -{ - PROPERTY (public, LDColor, color, setColor, STOCK_WRITE) - PROPERTY (public, QToolButton*, toolButton, setToolButton, STOCK_WRITE) - - public: - LDQuickColor (LDColor color, QToolButton* toolButton); - bool isSeparator() const; - - static LDQuickColor getSeparator(); -}; - -// -// Object list class for MainWindow -// -class ObjectList : public QListWidget -{ - Q_OBJECT - - protected: - void contextMenuEvent (QContextMenuEvent* ev); -}; - -// -// LDForge's main GUI class. -// -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit MainWindow (QWidget* parent = null, Qt::WindowFlags flags = 0); - ~MainWindow(); - - // Rebuilds the object list. - void buildObjList(); - - // Updates the window title. - void updateTitle(); - - // Builds the object list and tells the GL renderer to init a full - // refresh. - void doFullRefresh(); - - // Builds the object list and tells the GL renderer to do a soft update. - void refresh(); - - // Returns the suggested position to place a new object at. - int getInsertionPoint(); - - // Updates the quick color toolbar - void updateColorToolbar(); - - // Rebuilds the recent files submenu - void updateRecentFilesMenu(); - - // Sets the selection based on what's selected in the object list. - void updateSelection(); - - // Updates the grids, selects the selected grid and deselects others. - void updateGridToolBar(); - - // Updates the edit modes, current one is selected and others are deselected. - void updateEditModeActions(); - - // Rebuilds the document tab list. - void updateDocumentList(); - - // Updates the document tab for \c doc. If no such tab exists, the - // document list is rebuilt instead. - void updateDocumentListItem (LDDocument* doc); - - // Returns the uniform selected color (i.e. 4 if everything selected is - // red), -1 if there is no such consensus. - LDColor getSelectedColor(); - - // Automatically scrolls the object list so that it points to the first - // selected object. - void scrollToSelection(); - - // Spawns the context menu at the given position. - void spawnContextMenu (const QPoint pos); - - // Deletes all selected objects, returns the count of deleted objects. - int deleteSelection(); - - // Deletes all objects by the given color number. - void deleteByColor (LDColor color); - - // Tries to save the given document. - bool save (LDDocument* doc, bool saveAs); - - // Updates various actions, undo/redo are set enabled/disabled where - // appropriate, togglable actions are updated based on configuration, - // etc. - void updateActions(); - - // Returns a pointer to the renderer - inline GLRenderer* R() - { - return m_renderer; - } - - // Sets the quick color list to the given list of colors. - inline void setQuickColors (const QList& colors) - { - m_quickColors = colors; - updateColorToolbar(); - } - - // Adds a message to the renderer's message manager. - void addMessage (QString msg); - - // Updates the object list. Right now this just rebuilds it. - void refreshObjectList(); - - void endAction(); - - inline QTreeWidget* getPrimitivesTree() const - { - return ui->primitives; - } - - static QKeySequence defaultShortcut (QAction* act); - void loadShortcuts (QSettings const* settings); - void saveShortcuts (QSettings* settings); - void applyToActions (std::function function); - - bool ringToolHiRes() const; - int ringToolSegments() const; - -public slots: - void updatePrimitives(); - void changeCurrentFile(); - void closeTab (int tabindex); - void ringToolHiResClicked (bool clicked); - void circleToolSegmentsChanged(); - void slot_action(); - void slot_actionNew(); - void slot_actionNewFile(); - void slot_actionOpen(); - void slot_actionDownloadFrom(); - void slot_actionSave(); - void slot_actionSaveAs(); - void slot_actionSaveAll(); - void slot_actionClose(); - void slot_actionCloseAll(); - void slot_actionInsertFrom(); - void slot_actionExportTo(); - void slot_actionSettings(); - void slot_actionSetLDrawPath(); - void slot_actionScanPrimitives(); - void slot_actionExit(); - void slot_actionResetView(); - void slot_actionAxes(); - void slot_actionWireframe(); - void slot_actionBFCView(); - void slot_actionSetOverlay(); - void slot_actionClearOverlay(); - void slot_actionScreenshot(); - void slot_actionInsertRaw(); - void slot_actionNewSubfile(); - void slot_actionNewLine(); - void slot_actionNewTriangle(); - void slot_actionNewQuad(); - void slot_actionNewCLine(); - void slot_actionNewComment(); - void slot_actionNewBFC(); - void slot_actionNewVertex(); - void slot_actionUndo(); - void slot_actionRedo(); - void slot_actionCut(); - void slot_actionCopy(); - void slot_actionPaste(); - void slot_actionDelete(); - void slot_actionSelectAll(); - void slot_actionSelectByColor(); - void slot_actionSelectByType(); - void slot_actionModeDraw(); - void slot_actionModeSelect(); - void slot_actionModeRectangle(); - void slot_actionModeCircle(); - void slot_actionModeMagicWand(); - void slot_actionModeLinePath(); - void slot_actionSetDrawDepth(); - void slot_actionSetColor(); - void slot_actionAutocolor(); - void slot_actionUncolor(); - void slot_actionInline(); - void slot_actionInlineDeep(); - void slot_actionInvert(); - void slot_actionMakePrimitive(); - void slot_actionSplitQuads(); - void slot_actionEditRaw(); - void slot_actionBorders(); - void slot_actionRoundCoordinates(); - void slot_actionVisibilityHide(); - void slot_actionVisibilityReveal(); - void slot_actionVisibilityToggle(); - void slot_actionReplaceCoords(); - void slot_actionFlip(); - void slot_actionDemote(); - void slot_actionYtruder(); - void slot_actionRectifier(); - void slot_actionIntersector(); - void slot_actionIsecalc(); - void slot_actionCoverer(); - void slot_actionEdger2(); - void slot_actionHelp(); - void slot_actionAbout(); - void slot_actionAboutQt(); - void slot_actionGridCoarse(); - void slot_actionGridMedium(); - void slot_actionGridFine(); - void slot_actionEdit(); - void slot_actionMoveUp(); - void slot_actionMoveDown(); - void slot_actionMoveXNeg(); - void slot_actionMoveXPos(); - void slot_actionMoveYNeg(); - void slot_actionMoveYPos(); - void slot_actionMoveZNeg(); - void slot_actionMoveZPos(); - void slot_actionRotateXNeg(); - void slot_actionRotateXPos(); - void slot_actionRotateYNeg(); - void slot_actionRotateYPos(); - void slot_actionRotateZNeg(); - void slot_actionRotateZPos(); - void slot_actionRotationPoint(); - void slot_actionAddHistoryLine(); - void slot_actionJumpTo(); - void slot_actionSubfileSelection(); - void slot_actionDrawAngles(); - void slot_actionRandomColors(); - void slot_actionOpenSubfiles(); - void slot_actionSplitLines(); - void slot_actionDrawSurfaces(); - void slot_actionDrawEdgeLines(); - void slot_actionDrawConditionalLines(); - -protected: - void closeEvent (QCloseEvent* ev); - -private: - GLRenderer* m_renderer; - LDObjectList m_sel; - QList m_quickColors; - QList m_colorButtons; - QList m_recentFiles; - MessageManager* m_msglog; - Ui_LDForgeUI* ui; - QTabBar* m_tabs; - bool m_updatingTabs; - -private slots: - void slot_selectionChanged(); - void slot_recentFile(); - void slot_quickColor(); - void slot_lastSecondCleanup(); - void slot_editObject (QListWidgetItem* listitem); -}; - -//! Pointer to the instance of MainWindow. -extern MainWindow* g_win; - -//! Get an icon by name from the resources directory. -QPixmap GetIcon (QString iconName); - -//! \returns a list of quick colors based on the configuration entry. -QList LoadQuickColorList(); - -//! Asks the user a yes/no question with the given \c message and the given -//! window \c title. -//! \returns true if the user answered yes, false if no. -bool Confirm (const QString& title, const QString& message); // Generic confirm prompt - -//! An overload of \c confirm(), this asks the user a yes/no question with the -//! given \c message. -//! \returns true if the user answered yes, false if no. -bool Confirm (const QString& message); - -//! Displays an error prompt with the given \c message -void Critical (const QString& message); - -//! Makes an icon of \c size x \c size pixels to represent \c colinfo -QIcon MakeColorIcon (LDColor colinfo, const int size); - -//! Fills the given combo-box with color information -void MakeColorComboBox (QComboBox* box); - -//! \returns a QImage from the given raw GL \c data -QImage GetImageFromScreencap (uchar* data, int w, int h); - -//! -//! Takes in pairs of radio buttons and respective values and finds the first -//! selected one. -//! \returns returns the value of the first found radio button that was checked -//! \returns by the user. -//! -template -T RadioSwitch (const T& defval, QList> haystack) -{ - for (Pair i : haystack) - { - if (i.first->isChecked()) - return i.second; - } - - return defval; -} - -//! -//! Takes in pairs of radio buttons and respective values and checks the first -//! found radio button whose respsective value matches \c expr have the given value. -//! -template -void RadioDefault (const T& expr, QList> haystack) -{ - for (Pair i : haystack) - { - if (i.second == expr) - { - i.first->setChecked (true); - return; - } - } -} - -// ============================================================================= -// -class SubfileListItem : public QTreeWidgetItem -{ - PROPERTY (public, Primitive*, primitive, setPrimitive, STOCK_WRITE) - -public: - SubfileListItem (QTreeWidgetItem* parent, Primitive* info) : - QTreeWidgetItem (parent), - m_primitive (info) {} - - SubfileListItem (QTreeWidget* parent, Primitive* info) : - QTreeWidgetItem (parent), - m_primitive (info) {} -}; - -void PopulatePrimitives (QTreeWidget* tw, const QString& selectByDefault = QString()); diff -r f81445a7abde -r a4b463a7ee82 src/mainwindow.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mainwindow.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -0,0 +1,1190 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013, 2014 Teemu 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "main.h" +#include "glRenderer.h" +#include "mainwindow.h" +#include "ldDocument.h" +#include "configuration.h" +#include "miscallenous.h" +#include "colors.h" +#include "editHistory.h" +#include "radioGroup.h" +#include "addObjectDialog.h" +#include "messageLog.h" +#include "configuration.h" +#include "ui_ldforge.h" +#include "primitives.h" +#include "editmodes/abstractEditMode.h" + +static bool g_isSelectionLocked = false; +static QMap g_defaultShortcuts; + +CFGENTRY (Bool, ColorizeObjectsList, true) +CFGENTRY (String, QuickColorToolbar, "4:25:14:27:2:3:11:1:22:|:0:72:71:15") +CFGENTRY (Bool, ListImplicitFiles, false) +CFGENTRY (List, HiddenToolbars, {}) +EXTERN_CFGENTRY (List, RecentFiles) +EXTERN_CFGENTRY (Bool, DrawAxes) +EXTERN_CFGENTRY (String, MainColor) +EXTERN_CFGENTRY (Float, MainColorAlpha) +EXTERN_CFGENTRY (Bool, DrawWireframe) +EXTERN_CFGENTRY (Bool, BFCRedGreenView) +EXTERN_CFGENTRY (Bool, DrawAngles) +EXTERN_CFGENTRY (Bool, RandomColors) +EXTERN_CFGENTRY (Bool, DrawSurfaces) +EXTERN_CFGENTRY (Bool, DrawEdgeLines) +EXTERN_CFGENTRY (Bool, DrawConditionalLines) + +// ============================================================================= +// +MainWindow::MainWindow (QWidget* parent, Qt::WindowFlags flags) : + QMainWindow (parent, flags) +{ + g_win = this; + ui = new Ui_LDForgeUI; + ui->setupUi (this); + m_updatingTabs = false; + m_renderer = new GLRenderer (this); + m_tabs = new QTabBar; + m_tabs->setTabsClosable (true); + ui->verticalLayout->insertWidget (0, m_tabs); + + // Stuff the renderer into its frame + QVBoxLayout* rendererLayout = new QVBoxLayout (ui->rendererFrame); + rendererLayout->addWidget (R()); + + connect (ui->objectList, SIGNAL (itemSelectionChanged()), this, SLOT (slot_selectionChanged())); + connect (ui->objectList, SIGNAL (itemDoubleClicked (QListWidgetItem*)), this, SLOT (slot_editObject (QListWidgetItem*))); + connect (m_tabs, SIGNAL (currentChanged(int)), this, SLOT (changeCurrentFile())); + connect (m_tabs, SIGNAL (tabCloseRequested (int)), this, SLOT (closeTab (int))); + + if (ActivePrimitiveScanner() != null) + connect (ActivePrimitiveScanner(), SIGNAL (workDone()), this, SLOT (updatePrimitives())); + else + updatePrimitives(); + + m_msglog = new MessageManager; + m_msglog->setRenderer (R()); + m_renderer->setMessageLog (m_msglog); + m_quickColors = LoadQuickColorList(); + slot_selectionChanged(); + setStatusBar (new QStatusBar); + updateActions(); + + // Connect all actions and save default sequences + applyToActions ([&](QAction* act) + { + connect (act, SIGNAL (triggered()), this, SLOT (slot_action())); + g_defaultShortcuts[act] = act->shortcut(); + }); + + updateGridToolBar(); + updateEditModeActions(); + updateRecentFilesMenu(); + updateColorToolbar(); + updateTitle(); + loadShortcuts (Config::SettingsObject()); + setMinimumSize (300, 200); + connect (qApp, SIGNAL (aboutToQuit()), this, SLOT (slot_lastSecondCleanup())); + connect (ui->ringToolHiRes, SIGNAL (clicked (bool)), this, SLOT (ringToolHiResClicked (bool))); + connect (ui->ringToolSegments, SIGNAL (valueChanged (int)), + this, SLOT (circleToolSegmentsChanged())); + circleToolSegmentsChanged(); // invoke it manually for initial label text + + for (QVariant const& toolbarname : cfg::HiddenToolbars) + { + QToolBar* toolbar = findChild (toolbarname.toString()); + + if (toolbar != null) + toolbar->hide(); + } +} + +MainWindow::~MainWindow() +{ + g_win = null; +} + +// ============================================================================= +// +void MainWindow::slot_action() +{ + // Get the name of the sender object and use it to compose the slot name, + // then invoke this slot to call the action. + QMetaObject::invokeMethod (this, + qPrintable (format ("slot_%1", sender()->objectName())), Qt::DirectConnection); + endAction(); +} + +// ============================================================================= +// +void MainWindow::endAction() +{ + // Add a step in the history now. + CurrentDocument()->addHistoryStep(); + + // Update the list item of the current file - we may need to draw an icon + // now that marks it as having unsaved changes. + updateDocumentListItem (CurrentDocument()); + refresh(); +} + +// ============================================================================= +// +void MainWindow::slot_lastSecondCleanup() +{ + delete m_renderer; + delete ui; +} + +// ============================================================================= +// +void MainWindow::updateRecentFilesMenu() +{ + // First, clear any items in the recent files menu +for (QAction * recent : m_recentFiles) + delete recent; + + m_recentFiles.clear(); + + QAction* first = null; + + for (const QVariant& it : cfg::RecentFiles) + { + QString file = it.toString(); + QAction* recent = new QAction (GetIcon ("open-recent"), file, this); + + connect (recent, SIGNAL (triggered()), this, SLOT (slot_recentFile())); + ui->menuOpenRecent->insertAction (first, recent); + m_recentFiles << recent; + first = recent; + } +} + +// ============================================================================= +// +QList LoadQuickColorList() +{ + QList colors; + + for (QString colorname : cfg::QuickColorToolbar.split (":")) + { + if (colorname == "|") + colors << LDQuickColor::getSeparator(); + else + { + LDColor color = colorname.toInt(); + + if (color.isValid()) + colors << LDQuickColor (color, null); + } + } + + return colors; +} + +// ============================================================================= +// +void MainWindow::updateColorToolbar() +{ + m_colorButtons.clear(); + ui->toolBarColors->clear(); + ui->toolBarColors->addAction (ui->actionUncolor); + ui->toolBarColors->addSeparator(); + + for (LDQuickColor& entry : m_quickColors) + { + if (entry.isSeparator()) + { + ui->toolBarColors->addSeparator(); + } + else + { + QToolButton* colorButton = new QToolButton; + colorButton->setIcon (MakeColorIcon (entry.color(), 16)); + colorButton->setIconSize (QSize (16, 16)); + colorButton->setToolTip (entry.color().name()); + + connect (colorButton, SIGNAL (clicked()), this, SLOT (slot_quickColor())); + ui->toolBarColors->addWidget (colorButton); + m_colorButtons << colorButton; + + entry.setToolButton (colorButton); + } + } + + updateGridToolBar(); +} + +// ============================================================================= +// +void MainWindow::updateGridToolBar() +{ + // Ensure that the current grid - and only the current grid - is selected. + ui->actionGridCoarse->setChecked (cfg::Grid == Grid::Coarse); + ui->actionGridMedium->setChecked (cfg::Grid == Grid::Medium); + ui->actionGridFine->setChecked (cfg::Grid == Grid::Fine); +} + +// ============================================================================= +// +void MainWindow::updateTitle() +{ + QString title = format (APPNAME " " VERSION_STRING); + + // Append our current file if we have one + if (CurrentDocument()) + { + title += ": "; + title += CurrentDocument()->getDisplayName(); + + if (CurrentDocument()->getObjectCount() > 0 and + CurrentDocument()->getObject (0)->type() == OBJ_Comment) + { + // Append title + LDComment* comm = static_cast (CurrentDocument()->getObject (0)); + title += format (": %1", comm->text()); + } + + if (CurrentDocument()->hasUnsavedChanges()) + title += '*'; + } + +#ifdef DEBUG + title += " [debug build]"; +#elif BUILD_ID != BUILD_RELEASE + title += " [pre-release build]"; +#endif // DEBUG + + if (strlen (commitTimeString())) + title += format (" (%1)", QString::fromUtf8 (commitTimeString())); + + setWindowTitle (title); +} + +// ============================================================================= +// +int MainWindow::deleteSelection() +{ + if (Selection().isEmpty()) + return 0; + + LDObjectList selCopy = Selection(); + + // Delete the objects that were being selected + for (LDObject* obj : selCopy) + obj->destroy(); + + refresh(); + return selCopy.size(); +} + +// ============================================================================= +// +void MainWindow::buildObjList() +{ + if (not CurrentDocument()) + return; + + // Lock the selection while we do this so that refreshing the object list + // doesn't trigger selection updating so that the selection doesn't get lost + // while this is done. + g_isSelectionLocked = true; + + for (int i = 0; i < ui->objectList->count(); ++i) + delete ui->objectList->item (i); + + ui->objectList->clear(); + + for (LDObject* obj : CurrentDocument()->objects()) + { + QString descr; + + switch (obj->type()) + { + case OBJ_Comment: + { + descr = static_cast (obj)->text(); + + // Remove leading whitespace + while (descr[0] == ' ') + descr.remove (0, 1); + + break; + } + + case OBJ_Empty: + break; // leave it empty + + case OBJ_Line: + case OBJ_Triangle: + case OBJ_Quad: + case OBJ_CondLine: + { + for (int i = 0; i < obj->numVertices(); ++i) + { + if (i != 0) + descr += ", "; + + descr += obj->vertex (i).toString (true); + } + break; + } + + case OBJ_Error: + { + descr = format ("ERROR: %1", obj->asText()); + break; + } + + case OBJ_Subfile: + { + LDSubfile* ref = static_cast (obj); + + descr = format ("%1 %2, (", ref->fileInfo()->getDisplayName(), ref->position().toString (true)); + + for (int i = 0; i < 9; ++i) + descr += format ("%1%2", ref->transform()[i], (i != 8) ? " " : ""); + + descr += ')'; + break; + } + + case OBJ_BFC: + { + descr = LDBFC::StatementStrings[int (static_cast (obj)->statement())]; + break; + } + + case OBJ_Overlay: + { + LDOverlay* ovl = static_cast (obj); + descr = format ("[%1] %2 (%3, %4), %5 x %6", g_CameraNames[ovl->camera()], + Basename (ovl->fileName()), ovl->x(), ovl->y(), + ovl->width(), ovl->height()); + break; + } + + default: + { + descr = obj->typeName(); + break; + } + } + + QListWidgetItem* item = new QListWidgetItem (descr); + item->setIcon (GetIcon (obj->typeName())); + + // Use italic font if hidden + if (obj->isHidden()) + { + QFont font = item->font(); + font.setItalic (true); + item->setFont (font); + } + + // Color gibberish orange on red so it stands out. + if (obj->type() == OBJ_Error) + { + item->setBackground (QColor ("#AA0000")); + item->setForeground (QColor ("#FFAA00")); + } + else if (cfg::ColorizeObjectsList and obj->isColored() and + obj->color().isValid() and obj->color() != MainColor and obj->color() != EdgeColor) + { + // If the object isn't in the main or edge color, draw this list entry in that color. + item->setForeground (obj->color().faceColor()); + } + + obj->qObjListEntry = item; + ui->objectList->insertItem (ui->objectList->count(), item); + } + + g_isSelectionLocked = false; + updateSelection(); + scrollToSelection(); +} + +// ============================================================================= +// +void MainWindow::scrollToSelection() +{ + if (Selection().isEmpty()) + return; + + LDObject* obj = Selection().last(); + ui->objectList->scrollToItem (obj->qObjListEntry); +} + +// ============================================================================= +// +void MainWindow::slot_selectionChanged() +{ + if (g_isSelectionLocked == true or CurrentDocument() == null) + return; + + LDObjectList priorSelection = Selection(); + + // Get the objects from the object list selection + CurrentDocument()->clearSelection(); + const QList items = ui->objectList->selectedItems(); + + for (LDObject* obj : CurrentDocument()->objects()) + { + for (QListWidgetItem* item : items) + { + if (item == obj->qObjListEntry) + { + obj->select(); + break; + } + } + } + + // The select() method calls may have selected additional items (i.e. invertnexts) + // Update it all now. + updateSelection(); + + // Update the GL renderer + LDObjectList compound = priorSelection + Selection(); + RemoveDuplicates (compound); + + for (LDObject* obj : compound) + R()->compileObject (obj); + + R()->update(); +} + +// ============================================================================= +// +void MainWindow::slot_recentFile() +{ + QAction* qAct = static_cast (sender()); + OpenMainModel (qAct->text()); +} + +// ============================================================================= +// +void MainWindow::slot_quickColor() +{ + QToolButton* button = static_cast (sender()); + LDColor color = LDColor::nullColor(); + + for (const LDQuickColor& entry : m_quickColors) + { + if (entry.toolButton() == button) + { + color = entry.color(); + break; + } + } + + if (not color.isValid()) + return; + + for (LDObject* obj : Selection()) + { + if (not obj->isColored()) + continue; // uncolored object + + obj->setColor (color); + R()->compileObject (obj); + } + + endAction(); + refresh(); +} + +// ============================================================================= +// +int MainWindow::getInsertionPoint() +{ + // If we have a selection, put the item after it. + if (not Selection().isEmpty()) + return Selection().last()->lineNumber() + 1; + + // Otherwise place the object at the end. + return CurrentDocument()->getObjectCount(); +} + +// ============================================================================= +// +void MainWindow::doFullRefresh() +{ + buildObjList(); + m_renderer->hardRefresh(); +} + +// ============================================================================= +// +void MainWindow::refresh() +{ + buildObjList(); + m_renderer->update(); +} + +// ============================================================================= +// +void MainWindow::updateSelection() +{ + g_isSelectionLocked = true; + QItemSelection itemselect; + int top = -1; + int bottom = -1; + + for (LDObject* obj : Selection()) + { + if (obj->qObjListEntry == null) + continue; + + int row = ui->objectList->row (obj->qObjListEntry); + + if (top == -1) + { + top = bottom = row; + } + else + { + if (row != bottom + 1) + { + itemselect.select (ui->objectList->model()->index (top, 0), + ui->objectList->model()->index (bottom, 0)); + top = -1; + } + + bottom = row; + } + } + + if (top != -1) + { + itemselect.select (ui->objectList->model()->index (top, 0), + ui->objectList->model()->index (bottom, 0)); + } + + ui->objectList->selectionModel()->select (itemselect, QItemSelectionModel::ClearAndSelect); + g_isSelectionLocked = false; +} + +// ============================================================================= +// +LDColor MainWindow::getSelectedColor() +{ + LDColor result; + + for (LDObject* obj : Selection()) + { + if (not obj->isColored()) + continue; // This one doesn't use color so it doesn't have a say + + if (result.isValid() and obj->color() != result) + return LDColor::nullColor(); // No consensus in object color + + if (not result.isValid()) + result = obj->color(); + } + + return result; +} + +// ============================================================================= +// +void MainWindow::closeEvent (QCloseEvent* ev) +{ + // Check whether it's safe to close all files. + if (not IsSafeToCloseAll()) + { + ev->ignore(); + return; + } + + // Save the toolbar set + cfg::HiddenToolbars.clear(); + + for (QToolBar* toolbar : findChildren()) + { + if (toolbar->isHidden()) + cfg::HiddenToolbars << toolbar->objectName(); + } + + // Save the configuration before leaving. + Config::Save(); + ev->accept(); +} + +// ============================================================================= +// +void MainWindow::spawnContextMenu (const QPoint pos) +{ + const bool single = (Selection().size() == 1); + LDObject* singleObj = single ? Selection().first() : nullptr; + + bool hasSubfiles = false; + + for (LDObject* obj : Selection()) + { + if (obj->type() == OBJ_Subfile) + { + hasSubfiles = true; + break; + } + } + + QMenu* contextMenu = new QMenu; + + if (single and singleObj->type() != OBJ_Empty) + { + contextMenu->addAction (ui->actionEdit); + contextMenu->addSeparator(); + } + + contextMenu->addAction (ui->actionCut); + contextMenu->addAction (ui->actionCopy); + contextMenu->addAction (ui->actionPaste); + contextMenu->addAction (ui->actionDelete); + contextMenu->addSeparator(); + contextMenu->addAction (ui->actionSetColor); + + if (single) + contextMenu->addAction (ui->actionEditRaw); + + contextMenu->addAction (ui->actionBorders); + contextMenu->addAction (ui->actionSetOverlay); + contextMenu->addAction (ui->actionClearOverlay); + + if (hasSubfiles) + { + contextMenu->addSeparator(); + contextMenu->addAction (ui->actionOpenSubfiles); + } + + contextMenu->addSeparator(); + contextMenu->addAction (ui->actionModeSelect); + contextMenu->addAction (ui->actionModeDraw); + contextMenu->addAction (ui->actionModeCircle); + + if (not Selection().isEmpty()) + { + contextMenu->addSeparator(); + contextMenu->addAction (ui->actionSubfileSelection); + } + + if (R()->camera() != EFreeCamera) + { + contextMenu->addSeparator(); + contextMenu->addAction (ui->actionSetDrawDepth); + } + + contextMenu->exec (pos); +} + +// ============================================================================= +// +void MainWindow::deleteByColor (LDColor color) +{ + LDObjectList objs; + + for (LDObject* obj : CurrentDocument()->objects()) + { + if (not obj->isColored() or obj->color() != color) + continue; + + objs << obj; + } + + for (LDObject* obj : objs) + obj->destroy(); +} + +// ============================================================================= +// +void MainWindow::updateEditModeActions() +{ + const EditModeType mode = R()->currentEditModeType(); + ui->actionModeSelect->setChecked (mode == EditModeType::Select); + ui->actionModeDraw->setChecked (mode == EditModeType::Draw); + ui->actionModeRectangle->setChecked (mode == EditModeType::Rectangle); + ui->actionModeCircle->setChecked (mode == EditModeType::Circle); + ui->actionModeMagicWand->setChecked (mode == EditModeType::MagicWand); + ui->actionModeLinePath->setChecked (mode == EditModeType::LinePath); +} + +// ============================================================================= +// +void MainWindow::slot_editObject (QListWidgetItem* listitem) +{ + for (LDObject* it : CurrentDocument()->objects()) + { + if (it->qObjListEntry == listitem) + { + AddObjectDialog::staticDialog (it->type(), it); + break; + } + } +} + +// ============================================================================= +// +bool MainWindow::save (LDDocument* doc, bool saveAs) +{ + QString path = doc->fullPath(); + int64 savesize; + + if (saveAs or path.isEmpty()) + { + QString name = doc->defaultName(); + + if (not doc->fullPath().isEmpty()) + name = doc->fullPath(); + elif (not doc->name().isEmpty()) + name = doc->name(); + + name.replace ("\\", "/"); + path = QFileDialog::getSaveFileName (g_win, tr ("Save As"), + name, tr ("LDraw files (*.dat *.ldr)")); + + if (path.isEmpty()) + { + // User didn't give a file name, abort. + return false; + } + } + + if (doc->save (path, &savesize)) + { + if (doc == CurrentDocument()) + updateTitle(); + + print ("Saved to %1 (%2)", path, MakePrettyFileSize (savesize)); + + // Add it to recent files + AddRecentFile (path); + return true; + } + + QString message = format (tr ("Failed to save to %1: %2"), path, strerror (errno)); + + // Tell the user the save failed, and give the option for saving as with it. + QMessageBox dlg (QMessageBox::Critical, tr ("Save Failure"), message, QMessageBox::Close, g_win); + + // Add a save-as button + QPushButton* saveAsBtn = new QPushButton (tr ("Save As")); + saveAsBtn->setIcon (GetIcon ("file-save-as")); + dlg.addButton (saveAsBtn, QMessageBox::ActionRole); + dlg.setDefaultButton (QMessageBox::Close); + dlg.exec(); + + if (dlg.clickedButton() == saveAsBtn) + return save (doc, true); // yay recursion! + + return false; +} + +void MainWindow::addMessage (QString msg) +{ + m_msglog->addLine (msg); +} + +// ============================================================================ +void ObjectList::contextMenuEvent (QContextMenuEvent* ev) +{ + g_win->spawnContextMenu (ev->globalPos()); +} + +// ============================================================================= +// +QPixmap GetIcon (QString iconName) +{ + return (QPixmap (format (":/icons/%1.png", iconName))); +} + +// ============================================================================= +// +bool Confirm (const QString& message) +{ + return Confirm (MainWindow::tr ("Confirm"), message); +} + +// ============================================================================= +// +bool Confirm (const QString& title, const QString& message) +{ + return QMessageBox::question (g_win, title, message, + (QMessageBox::Yes | QMessageBox::No), QMessageBox::No) == QMessageBox::Yes; +} + +// ============================================================================= +// +void Critical (const QString& message) +{ + QMessageBox::critical (g_win, MainWindow::tr ("Error"), message, + (QMessageBox::Close), QMessageBox::Close); +} + +// ============================================================================= +// +QIcon MakeColorIcon (LDColor colinfo, const int size) +{ + // Create an image object and link a painter to it. + QImage img (size, size, QImage::Format_ARGB32); + QPainter paint (&img); + QColor col = colinfo.faceColor(); + + if (colinfo == MainColor) + { + // Use the user preferences for main color here + col = cfg::MainColor; + col.setAlphaF (cfg::MainColorAlpha); + } + + // Paint the icon border + paint.fillRect (QRect (0, 0, size, size), colinfo.edgeColor()); + + // Paint the checkerboard background, visible with translucent icons + paint.drawPixmap (QRect (1, 1, size - 2, size - 2), GetIcon ("checkerboard"), QRect (0, 0, 8, 8)); + + // Paint the color above the checkerboard + paint.fillRect (QRect (1, 1, size - 2, size - 2), col); + return QIcon (QPixmap::fromImage (img)); +} + +// ============================================================================= +// +void MakeColorComboBox (QComboBox* box) +{ + std::map counts; + + for (LDObject* obj : CurrentDocument()->objects()) + { + if (not obj->isColored() or not obj->color().isValid()) + continue; + + if (counts.find (obj->color()) == counts.end()) + counts[obj->color()] = 1; + else + counts[obj->color()]++; + } + + box->clear(); + int row = 0; + + for (const auto& pair : counts) + { + QIcon ico = MakeColorIcon (pair.first, 16); + box->addItem (ico, format ("[%1] %2 (%3 object%4)", + pair.first, pair.first.name(), pair.second, Plural (pair.second))); + box->setItemData (row, pair.first.index()); + + ++row; + } +} + +// ============================================================================= +// +void MainWindow::updateDocumentList() +{ + m_updatingTabs = true; + + while (m_tabs->count() > 0) + m_tabs->removeTab (0); + + for (LDDocument* f : LDDocument::explicitDocuments()) + { + // Add an item to the list for this file and store the tab index + // in the document so we can find documents by tab index. + f->setTabIndex (m_tabs->addTab ("")); + updateDocumentListItem (f); + } + + m_updatingTabs = false; +} + +// ============================================================================= +// +void MainWindow::updateDocumentListItem (LDDocument* doc) +{ + bool oldUpdatingTabs = m_updatingTabs; + m_updatingTabs = true; + + if (doc->tabIndex() == -1) + { + // We don't have a list item for this file, so the list either doesn't + // exist yet or is out of date. Build the list now. + updateDocumentList(); + return; + } + + // If this is the current file, it also needs to be the selected item on + // the list. + if (doc == CurrentDocument()) + m_tabs->setCurrentIndex (doc->tabIndex()); + + m_tabs->setTabText (doc->tabIndex(), doc->getDisplayName()); + + // If the document.has unsaved changes, draw a little icon next to it to mark that. + m_tabs->setTabIcon (doc->tabIndex(), doc->hasUnsavedChanges() ? GetIcon ("file-save") : QIcon()); + m_tabs->setTabData (doc->tabIndex(), doc->name()); + m_updatingTabs = oldUpdatingTabs; +} + +// ============================================================================= +// +// A file is selected from the list of files on the left of the screen. Find out +// which file was picked and change to it. +// +void MainWindow::changeCurrentFile() +{ + if (m_updatingTabs) + return; + + LDDocument* file = nullptr; + int tabIndex = m_tabs->currentIndex(); + + // Find the file pointer of the item that was selected. + for (LDDocument* it : LDDocument::explicitDocuments()) + { + if (it->tabIndex() == tabIndex) + { + file = it; + break; + } + } + + // If we picked the same file we're currently on, we don't need to do + // anything. + if (file == null or file == CurrentDocument()) + return; + + LDDocument::setCurrent (file); +} + +// ============================================================================= +// +void MainWindow::refreshObjectList() +{ +#if 0 + ui->objectList->clear(); + LDDocument* f = getCurrentDocument(); + +for (LDObject* obj : *f) + ui->objectList->addItem (obj->qObjListEntry); + +#endif + + buildObjList(); +} + +// ============================================================================= +// +void MainWindow::updateActions() +{ + if (CurrentDocument() != null and CurrentDocument()->history() != null) + { + History* his = CurrentDocument()->history(); + int pos = his->position(); + ui->actionUndo->setEnabled (pos != -1); + ui->actionRedo->setEnabled (pos < (long) his->getSize() - 1); + } + + ui->actionWireframe->setChecked (cfg::DrawWireframe); + ui->actionAxes->setChecked (cfg::DrawAxes); + ui->actionBFCView->setChecked (cfg::BFCRedGreenView); + ui->actionRandomColors->setChecked (cfg::RandomColors); + ui->actionDrawAngles->setChecked (cfg::DrawAngles); + ui->actionDrawSurfaces->setChecked (cfg::DrawSurfaces); + ui->actionDrawEdgeLines->setChecked (cfg::DrawEdgeLines); + ui->actionDrawConditionalLines->setChecked (cfg::DrawConditionalLines); +} + +// ============================================================================= +// +void MainWindow::updatePrimitives() +{ + PopulatePrimitives (ui->primitives); +} + +// ============================================================================= +// +void MainWindow::closeTab (int tabindex) +{ + LDDocument* doc = FindDocument (m_tabs->tabData (tabindex).toString()); + + if (doc == null) + return; + + doc->dismiss(); +} + +// ============================================================================= +// +void MainWindow::loadShortcuts (QSettings const* settings) +{ + for (QAction* act : findChildren()) + { + QKeySequence seq = settings->value ("shortcut_" + act->objectName(), act->shortcut()).value(); + act->setShortcut (seq); + } +} + +// ============================================================================= +// +void MainWindow::saveShortcuts (QSettings* settings) +{ + applyToActions ([&](QAction* act) + { + QString const key = "shortcut_" + act->objectName(); + + if (g_defaultShortcuts[act] != act->shortcut()) + settings->setValue (key, act->shortcut()); + else + settings->remove (key); + }); +} + +// ============================================================================= +// +void MainWindow::applyToActions (std::function function) +{ + for (QAction* act : findChildren()) + { + if (not act->objectName().isEmpty()) + function (act); + } +} + +// ============================================================================= +// +QKeySequence MainWindow::defaultShortcut (QAction* act) // [static] +{ + return g_defaultShortcuts[act]; +} + +// ============================================================================= +// +bool MainWindow::ringToolHiRes() const +{ + return ui->ringToolHiRes->isChecked(); +} + +// ============================================================================= +// +int MainWindow::ringToolSegments() const +{ + return ui->ringToolSegments->value(); +} + +// ============================================================================= +// +void MainWindow::ringToolHiResClicked (bool checked) +{ + if (checked) + { + ui->ringToolSegments->setMaximum (HighResolution); + ui->ringToolSegments->setValue (ui->ringToolSegments->value() * 3); + } + else + { + ui->ringToolSegments->setValue (ui->ringToolSegments->value() / 3); + ui->ringToolSegments->setMaximum (LowResolution); + } +} + +// ============================================================================= +// +void MainWindow::circleToolSegmentsChanged() +{ + int numerator (ui->ringToolSegments->value()); + int denominator (ui->ringToolHiRes->isChecked() ? HighResolution : LowResolution); + Simplify (numerator, denominator); + ui->ringToolSegmentsLabel->setText (format ("%1 / %2", numerator, denominator)); +} + +// ============================================================================= +// +QImage GetImageFromScreencap (uchar* data, int w, int h) +{ + // GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well. + return QImage (data, w, h, QImage::Format_ARGB32).rgbSwapped().mirrored(); +} + +// ============================================================================= +// +LDQuickColor::LDQuickColor (LDColor color, QToolButton* toolButton) : + m_color (color), + m_toolButton (toolButton) {} + +// ============================================================================= +// +LDQuickColor LDQuickColor::getSeparator() +{ + return LDQuickColor (LDColor::nullColor(), null); +} + +// ============================================================================= +// +bool LDQuickColor::isSeparator() const +{ + return color() == LDColor::nullColor(); +} + +void PopulatePrimitives (QTreeWidget* tw, QString const& selectByDefault) +{ + tw->clear(); + + for (PrimitiveCategory* cat : g_PrimitiveCategories) + { + SubfileListItem* parentItem = new SubfileListItem (tw, null); + parentItem->setText (0, cat->name()); + QList subfileItems; + + for (Primitive& prim : cat->prims) + { + SubfileListItem* item = new SubfileListItem (parentItem, &prim); + item->setText (0, format ("%1 - %2", prim.name, prim.title)); + subfileItems << item; + + // If this primitive is the one the current object points to, + // select it by default + if (selectByDefault == prim.name) + tw->setCurrentItem (item); + } + + tw->addTopLevelItem (parentItem); + } +} diff -r f81445a7abde -r a4b463a7ee82 src/mainwindow.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mainwindow.h Sun Aug 30 04:53:37 2015 +0300 @@ -0,0 +1,391 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013, 2014 Teemu 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 . + */ + +#pragma once +#include +#include +#include +#include +#include +#include "configuration.h" +#include "ldObject.h" +#include "ui_ldforge.h" +#include "colors.h" + +class MessageManager; +class MainWindow; +class QToolButton; +class QDialogButtonBox; +class GLRenderer; +class QComboBox; +class QProgressBar; +class Ui_LDForgeUI; +struct Primitive; + +// Stuff for dialogs +#define IMPLEMENT_DIALOG_BUTTONS \ + bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel); \ + connect (bbx_buttons, SIGNAL (accepted()), this, SLOT (accept())); \ + connect (bbx_buttons, SIGNAL (rejected()), this, SLOT (reject())); \ + +class LDQuickColor +{ + PROPERTY (public, LDColor, color, setColor, STOCK_WRITE) + PROPERTY (public, QToolButton*, toolButton, setToolButton, STOCK_WRITE) + + public: + LDQuickColor (LDColor color, QToolButton* toolButton); + bool isSeparator() const; + + static LDQuickColor getSeparator(); +}; + +// +// Object list class for MainWindow +// +class ObjectList : public QListWidget +{ + Q_OBJECT + + protected: + void contextMenuEvent (QContextMenuEvent* ev); +}; + +// +// LDForge's main GUI class. +// +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow (QWidget* parent = null, Qt::WindowFlags flags = 0); + ~MainWindow(); + + // Rebuilds the object list. + void buildObjList(); + + // Updates the window title. + void updateTitle(); + + // Builds the object list and tells the GL renderer to init a full + // refresh. + void doFullRefresh(); + + // Builds the object list and tells the GL renderer to do a soft update. + void refresh(); + + // Returns the suggested position to place a new object at. + int getInsertionPoint(); + + // Updates the quick color toolbar + void updateColorToolbar(); + + // Rebuilds the recent files submenu + void updateRecentFilesMenu(); + + // Sets the selection based on what's selected in the object list. + void updateSelection(); + + // Updates the grids, selects the selected grid and deselects others. + void updateGridToolBar(); + + // Updates the edit modes, current one is selected and others are deselected. + void updateEditModeActions(); + + // Rebuilds the document tab list. + void updateDocumentList(); + + // Updates the document tab for \c doc. If no such tab exists, the + // document list is rebuilt instead. + void updateDocumentListItem (LDDocument* doc); + + // Returns the uniform selected color (i.e. 4 if everything selected is + // red), -1 if there is no such consensus. + LDColor getSelectedColor(); + + // Automatically scrolls the object list so that it points to the first + // selected object. + void scrollToSelection(); + + // Spawns the context menu at the given position. + void spawnContextMenu (const QPoint pos); + + // Deletes all selected objects, returns the count of deleted objects. + int deleteSelection(); + + // Deletes all objects by the given color number. + void deleteByColor (LDColor color); + + // Tries to save the given document. + bool save (LDDocument* doc, bool saveAs); + + // Updates various actions, undo/redo are set enabled/disabled where + // appropriate, togglable actions are updated based on configuration, + // etc. + void updateActions(); + + // Returns a pointer to the renderer + inline GLRenderer* R() + { + return m_renderer; + } + + // Sets the quick color list to the given list of colors. + inline void setQuickColors (const QList& colors) + { + m_quickColors = colors; + updateColorToolbar(); + } + + // Adds a message to the renderer's message manager. + void addMessage (QString msg); + + // Updates the object list. Right now this just rebuilds it. + void refreshObjectList(); + + void endAction(); + + inline QTreeWidget* getPrimitivesTree() const + { + return ui->primitives; + } + + static QKeySequence defaultShortcut (QAction* act); + void loadShortcuts (QSettings const* settings); + void saveShortcuts (QSettings* settings); + void applyToActions (std::function function); + + bool ringToolHiRes() const; + int ringToolSegments() const; + +public slots: + void updatePrimitives(); + void changeCurrentFile(); + void closeTab (int tabindex); + void ringToolHiResClicked (bool clicked); + void circleToolSegmentsChanged(); + void slot_action(); + void slot_actionNew(); + void slot_actionNewFile(); + void slot_actionOpen(); + void slot_actionDownloadFrom(); + void slot_actionSave(); + void slot_actionSaveAs(); + void slot_actionSaveAll(); + void slot_actionClose(); + void slot_actionCloseAll(); + void slot_actionInsertFrom(); + void slot_actionExportTo(); + void slot_actionSettings(); + void slot_actionSetLDrawPath(); + void slot_actionScanPrimitives(); + void slot_actionExit(); + void slot_actionResetView(); + void slot_actionAxes(); + void slot_actionWireframe(); + void slot_actionBFCView(); + void slot_actionSetOverlay(); + void slot_actionClearOverlay(); + void slot_actionScreenshot(); + void slot_actionInsertRaw(); + void slot_actionNewSubfile(); + void slot_actionNewLine(); + void slot_actionNewTriangle(); + void slot_actionNewQuad(); + void slot_actionNewCLine(); + void slot_actionNewComment(); + void slot_actionNewBFC(); + void slot_actionNewVertex(); + void slot_actionUndo(); + void slot_actionRedo(); + void slot_actionCut(); + void slot_actionCopy(); + void slot_actionPaste(); + void slot_actionDelete(); + void slot_actionSelectAll(); + void slot_actionSelectByColor(); + void slot_actionSelectByType(); + void slot_actionModeDraw(); + void slot_actionModeSelect(); + void slot_actionModeRectangle(); + void slot_actionModeCircle(); + void slot_actionModeMagicWand(); + void slot_actionModeLinePath(); + void slot_actionSetDrawDepth(); + void slot_actionSetColor(); + void slot_actionAutocolor(); + void slot_actionUncolor(); + void slot_actionInline(); + void slot_actionInlineDeep(); + void slot_actionInvert(); + void slot_actionMakePrimitive(); + void slot_actionSplitQuads(); + void slot_actionEditRaw(); + void slot_actionBorders(); + void slot_actionRoundCoordinates(); + void slot_actionVisibilityHide(); + void slot_actionVisibilityReveal(); + void slot_actionVisibilityToggle(); + void slot_actionReplaceCoords(); + void slot_actionFlip(); + void slot_actionDemote(); + void slot_actionYtruder(); + void slot_actionRectifier(); + void slot_actionIntersector(); + void slot_actionIsecalc(); + void slot_actionCoverer(); + void slot_actionEdger2(); + void slot_actionHelp(); + void slot_actionAbout(); + void slot_actionAboutQt(); + void slot_actionGridCoarse(); + void slot_actionGridMedium(); + void slot_actionGridFine(); + void slot_actionEdit(); + void slot_actionMoveUp(); + void slot_actionMoveDown(); + void slot_actionMoveXNeg(); + void slot_actionMoveXPos(); + void slot_actionMoveYNeg(); + void slot_actionMoveYPos(); + void slot_actionMoveZNeg(); + void slot_actionMoveZPos(); + void slot_actionRotateXNeg(); + void slot_actionRotateXPos(); + void slot_actionRotateYNeg(); + void slot_actionRotateYPos(); + void slot_actionRotateZNeg(); + void slot_actionRotateZPos(); + void slot_actionRotationPoint(); + void slot_actionAddHistoryLine(); + void slot_actionJumpTo(); + void slot_actionSubfileSelection(); + void slot_actionDrawAngles(); + void slot_actionRandomColors(); + void slot_actionOpenSubfiles(); + void slot_actionSplitLines(); + void slot_actionDrawSurfaces(); + void slot_actionDrawEdgeLines(); + void slot_actionDrawConditionalLines(); + +protected: + void closeEvent (QCloseEvent* ev); + +private: + GLRenderer* m_renderer; + LDObjectList m_sel; + QList m_quickColors; + QList m_colorButtons; + QList m_recentFiles; + MessageManager* m_msglog; + Ui_LDForgeUI* ui; + QTabBar* m_tabs; + bool m_updatingTabs; + +private slots: + void slot_selectionChanged(); + void slot_recentFile(); + void slot_quickColor(); + void slot_lastSecondCleanup(); + void slot_editObject (QListWidgetItem* listitem); +}; + +//! Pointer to the instance of MainWindow. +extern MainWindow* g_win; + +//! Get an icon by name from the resources directory. +QPixmap GetIcon (QString iconName); + +//! \returns a list of quick colors based on the configuration entry. +QList LoadQuickColorList(); + +//! Asks the user a yes/no question with the given \c message and the given +//! window \c title. +//! \returns true if the user answered yes, false if no. +bool Confirm (const QString& title, const QString& message); // Generic confirm prompt + +//! An overload of \c confirm(), this asks the user a yes/no question with the +//! given \c message. +//! \returns true if the user answered yes, false if no. +bool Confirm (const QString& message); + +//! Displays an error prompt with the given \c message +void Critical (const QString& message); + +//! Makes an icon of \c size x \c size pixels to represent \c colinfo +QIcon MakeColorIcon (LDColor colinfo, const int size); + +//! Fills the given combo-box with color information +void MakeColorComboBox (QComboBox* box); + +//! \returns a QImage from the given raw GL \c data +QImage GetImageFromScreencap (uchar* data, int w, int h); + +//! +//! Takes in pairs of radio buttons and respective values and finds the first +//! selected one. +//! \returns returns the value of the first found radio button that was checked +//! \returns by the user. +//! +template +T RadioSwitch (const T& defval, QList> haystack) +{ + for (Pair i : haystack) + { + if (i.first->isChecked()) + return i.second; + } + + return defval; +} + +//! +//! Takes in pairs of radio buttons and respective values and checks the first +//! found radio button whose respsective value matches \c expr have the given value. +//! +template +void RadioDefault (const T& expr, QList> haystack) +{ + for (Pair i : haystack) + { + if (i.second == expr) + { + i.first->setChecked (true); + return; + } + } +} + +// ============================================================================= +// +class SubfileListItem : public QTreeWidgetItem +{ + PROPERTY (public, Primitive*, primitive, setPrimitive, STOCK_WRITE) + +public: + SubfileListItem (QTreeWidgetItem* parent, Primitive* info) : + QTreeWidgetItem (parent), + m_primitive (info) {} + + SubfileListItem (QTreeWidget* parent, Primitive* info) : + QTreeWidgetItem (parent), + m_primitive (info) {} +}; + +void PopulatePrimitives (QTreeWidget* tw, const QString& selectByDefault = QString()); diff -r f81445a7abde -r a4b463a7ee82 src/mainwindow.ui --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mainwindow.ui Sun Aug 30 04:53:37 2015 +0300 @@ -0,0 +1,1713 @@ + + + LDForgeUI + + + + 0 + 0 + 1010 + 641 + + + + + + + + :/icons/ldforge.png:/icons/ldforge.png + + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 0 + + + + + 0 + 0 + 234 + 402 + + + + Document + + + + + + + 0 + 0 + + + + QAbstractItemView::ExtendedSelection + + + + + + + + + 0 + 0 + 234 + 402 + + + + Tool Options + + + + + + Circle Tool Options + + + + + + + + High resolution + + + + + + + Segments: + + + + + + + + + true + + + 1 + + + 16 + + + 16 + + + + + + + a / b + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 0 + 0 + 234 + 402 + + + + Primitives + + + + + + QAbstractItemView::DragOnly + + + false + + + + 1 + + + + + + + + + + + + + + + + 0 + 0 + 1010 + 30 + + + + + Fi&le + + + + Open &Recent... + + + + :/icons/open-recent.png:/icons/open-recent.png + + + + + + + + + + + + + + + + + + + + + + + + + + + &View + + + + + + + + + + + + + + + + + + + + I&nsert + + + + + + + + + + + + + + + Edit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + E&xternal Tools + + + + + + + + + + + Help + + + + + + + + + &Move + + + + &Grids + + + + + + + + &Move Objects + + + + + + + + + + + &Object List + + + + + + + &Rotate + + + + + + + + + + + + + + + + + + + + + + + + + + + + File + + + TopToolBarArea + + + false + + + + + + + + + + New Object + + + TopToolBarArea + + + false + + + + + + + + + + + + + Basic tools + + + TopToolBarArea + + + false + + + + + + + + + + + Select + + + TopToolBarArea + + + false + + + + + + + + Grid + + + TopToolBarArea + + + false + + + + + + + + Display options + + + TopToolBarArea + + + true + + + + + + + + + + Editing tools + + + TopToolBarArea + + + false + + + + + + + + + + + + + + + + + Editing modes + + + LeftToolBarArea + + + false + + + + + + + + + + + Colors + + + RightToolBarArea + + + false + + + + + External Programs + + + TopToolBarArea + + + false + + + + + + + + + + + + :/icons/brick.png:/icons/brick.png + + + &New Part + + + Create a new part model. + + + Ctrl+N + + + + + + :/icons/file-open.png:/icons/file-open.png + + + &Open + + + Load a part model from a file. + + + Ctrl+O + + + + + + :/icons/file-save.png:/icons/file-save.png + + + &Save + + + Save the part model. + + + + + + Ctrl+S + + + + + + :/icons/file-save-as.png:/icons/file-save-as.png + + + Sa&ve As.. + + + Save the part model to a specific file. + + + Ctrl+Shift+S + + + + + + :/icons/file-import.png:/icons/file-import.png + + + &Insert From.. + + + + + + :/icons/file-export.png:/icons/file-export.png + + + &Export To.. + + + + + + :/icons/settings.png:/icons/settings.png + + + Settin&gs + + + Edit the settings of LDForge. + + + + + + + + + :/icons/settings.png:/icons/settings.png + + + Set &LDraw Path + + + Change the LDraw directory path. + + + + + + :/icons/radial.png:/icons/radial.png + + + Scan &Primitives + + + Scan the primitives folder for primitive info. Use this if you add new primitives. + + + + + + :/icons/exit.png:/icons/exit.png + + + E&xit + + + Ctrl+Q + + + + + &Reset View + + + + + true + + + true + + + + :/icons/axes.png:/icons/axes.png + + + &Draw Axes + + + + + true + + + + :/icons/wireframe.png:/icons/wireframe.png + + + &Wireframe + + + + + true + + + + :/icons/bfc-view.png:/icons/bfc-view.png + + + &BFC Red/Green View + + + Shift+B + + + + + + :/icons/overlay.png:/icons/overlay.png + + + &Set Overlay Image + + + + + + :/icons/overlay-clear.png:/icons/overlay-clear.png + + + &Clear Overlay Image + + + + + + :/icons/screencap.png:/icons/screencap.png + + + Screens&hot + + + + + &LDraw Code.. + + + + + + :/icons/add-line.png:/icons/add-line.png + + + N&ew Line + + + + + + :/icons/add-subfile.png:/icons/add-subfile.png + + + &New Subfile Reference + + + + + + :/icons/add-triangle.png:/icons/add-triangle.png + + + Ne&w Triangle + + + + + + :/icons/add-quad.png:/icons/add-quad.png + + + New &Quadrilateral + + + + + + :/icons/add-condline.png:/icons/add-condline.png + + + New &Conditional Line + + + + + + :/icons/add-comment.png:/icons/add-comment.png + + + New C&omment + + + + + + :/icons/add-bfc.png:/icons/add-bfc.png + + + New &BFC Statement + + + + + + :/icons/add-vertex.png:/icons/add-vertex.png + + + New &Vertex + + + + + + :/icons/undo.png:/icons/undo.png + + + &Undo + + + Undo a step. + + + Ctrl+Z + + + + + + :/icons/redo.png:/icons/redo.png + + + &Redo + + + Redo a step. + + + Ctrl+Shift+Z + + + + + + :/icons/cut.png:/icons/cut.png + + + &Cut + + + Cut the current selection to clipboard. + + + Ctrl+X + + + + + + :/icons/copy.png:/icons/copy.png + + + C&opy + + + Copy the current selection to clipboard. + + + + + + Ctrl+C + + + + + + :/icons/paste.png:/icons/paste.png + + + &Paste + + + Paste clipboard contents. + + + Ctrl+V + + + + + + :/icons/delete.png:/icons/delete.png + + + &Delete + + + Delete the selection + + + Del + + + + + + :/icons/select-all.png:/icons/select-all.png + + + &Select All + + + Ctrl+A + + + + + + :/icons/select-color.png:/icons/select-color.png + + + Select &by Color + + + + + + :/icons/select-type.png:/icons/select-type.png + + + Select b&y Type + + + + + true + + + true + + + + :/icons/mode-select.png:/icons/mode-select.png + + + Select Mode + + + S + + + + + true + + + + :/icons/mode-draw.png:/icons/mode-draw.png + + + Dra&w Mode + + + D + + + + + Set Draw Dept&h + + + + + + :/icons/palette.png:/icons/palette.png + + + &Set Color + + + Set the color on given objects. + + + Shift+C + + + + + + :/icons/autocolor.png:/icons/autocolor.png + + + &Auto-color + + + Set the color of the given object to the first found unused color. + + + Ctrl+Shift+C + + + + + + :/icons/uncolorize.png:/icons/uncolorize.png + + + &Uncolor + + + Uncolor + + + Reduce colors of everything selected to main and edge colors + + + + + + :/icons/inline.png:/icons/inline.png + + + I&nline + + + Inline selected subfiles. + + + Ctrl+I + + + + + + :/icons/inline-deep.png:/icons/inline-deep.png + + + &Deep Inline + + + Recursively inline selected subfiles down to polygons only. + + + Ctrl+Shift+I + + + + + + :/icons/invert.png:/icons/invert.png + + + &Invert + + + Ctrl+Shift+W + + + + + + :/icons/radial.png:/icons/radial.png + + + &Generate Primitive + + + + + + :/icons/quad-split.png:/icons/quad-split.png + + + Split &Quads + + + Split quads into triangles. + + + + + + :/icons/set-contents.png:/icons/set-contents.png + + + &Edit LDraw Code + + + Edit the LDraw code of this object. + + + + + + :/icons/make-borders.png:/icons/make-borders.png + + + &Make Borders + + + Add borders around given polygons. + + + + + + :/icons/round-coords.png:/icons/round-coords.png + + + &Round Coordinates + + + Round coordinates down to 3/4 decimals + + + + + + :/icons/visibility-toggle.png:/icons/visibility-toggle.png + + + &Toggle Visibility + + + Toggles visibility/hiding on objects. + + + + + + :/icons/replace-coords.png:/icons/replace-coords.png + + + Re&place Coordinates + + + Find and replace coordinate values. + + + + + + :/icons/flip.png:/icons/flip.png + + + &Flip + + + Flip coordinates. + + + Ctrl+Shift+F + + + + + Demote Conditional Lines + + + Demote conditional lines down to normal lines. + + + + + + :/icons/ytruder.png:/icons/ytruder.png + + + &Ytruder + + + Extrude selected lines to a given plane + + + + + + :/icons/rectifier.png:/icons/rectifier.png + + + &Rectifier + + + Optimizes quads into rect primitives. + + + + + + :/icons/intersector.png:/icons/intersector.png + + + &Intersector + + + Perform clipping between two input groups. + + + + + + :/icons/isecalc.png:/icons/isecalc.png + + + I&secalc + + + Compute intersection edgelines between two input groups. + + + + + + :/icons/coverer.png:/icons/coverer.png + + + &Coverer + + + Fill the space between two line shapes + + + + + &Edger 2 + + + + + false + + + + :/icons/help.png:/icons/help.png + + + &Help + + + F1 + + + + + + :/icons/ldforge.png:/icons/ldforge.png + + + &About LDForge + + + + + About &Qt + + + + + true + + + + :/icons/grid-coarse.png:/icons/grid-coarse.png + + + &Coarse Grid + + + + + true + + + true + + + + :/icons/grid-medium.png:/icons/grid-medium.png + + + &Medium Grid + + + + + true + + + + :/icons/grid-fine.png:/icons/grid-fine.png + + + &Fine Grid + + + + + &Edit Selected Object + + + + + + :/icons/arrow-up.png:/icons/arrow-up.png + + + &Move Up + + + PgUp + + + + + + :/icons/arrow-down.png:/icons/arrow-down.png + + + Move &Down + + + PgDown + + + + + + :/icons/move-x-neg.png:/icons/move-x-neg.png + + + &Move -X + + + Left + + + + + + :/icons/move-x-pos.png:/icons/move-x-pos.png + + + Move +&X + + + Right + + + + + + :/icons/move-y-neg.png:/icons/move-y-neg.png + + + Move -&Y + + + Home + + + + + + :/icons/move-y-pos.png:/icons/move-y-pos.png + + + M&ove +Y + + + End + + + + + + :/icons/move-z-neg.png:/icons/move-z-neg.png + + + Move -&Z + + + Down + + + + + + :/icons/move-z-pos.png:/icons/move-z-pos.png + + + Mo&ve +Z + + + Up + + + + + &Rotate -X + + + Ctrl+Left + + + + + Rotate +&X + + + Ctrl+Right + + + + + Rotate -&Y + + + Ctrl+End + + + + + R&otate +Y + + + Ctrl+Home + + + + + Rotate -&Z + + + Ctrl+Down + + + + + Rotat&e +Z + + + Ctrl+Up + + + + + &Set Rotation Point + + + + + Save All + + + + + &Close + + + Ctrl+W + + + + + Close All + + + Ctrl+Shift+W + + + + + + :/icons/file-new.png:/icons/file-new.png + + + New &File + + + Ctrl+N + + + + + &Download From... + + + + + Add History Line + + + + + &Go to Line... + + + Ctrl+G + + + + + true + + + + :/icons/mode-circle.png:/icons/mode-circle.png + + + C&ircle Mode + + + C + + + + + + :/icons/visibility-hide.png:/icons/visibility-hide.png + + + &Hide + + + Hides objects from view + + + + + + :/icons/visibility-show.png:/icons/visibility-show.png + + + Re&veal + + + Reveals objects. Undoes hiding. + + + + + Subfile Selection + + + + + true + + + + :/icons/mode-angle.png:/icons/mode-angle.png + + + Draw An&gles + + + Draw angle information when drawing lines + + + + + true + + + + :/icons/random-colors.png:/icons/random-colors.png + + + Ra&ndom colors + + + Shift+R + + + + + &Open Subfiles for Editing + + + Opens the documents used by the selected subparts for editing. + + + + + Split &Lines... + + + + + true + + + Draw s&urfaces + + + Render surfaces (i.e. quads and triangles) on the viewport. + + + + + true + + + Draw &edgelines + + + Render edgelines on the viewport + + + + + true + + + Draw conditional &lines + + + Render conditional lines on the viewport. + + + + + true + + + + :/icons/mode-magicwand.png:/icons/mode-magicwand.png + + + &Magic wand + + + W + + + + + true + + + + :/icons/mode-rectangle.png:/icons/mode-rectangle.png + + + Recta&ngle Mode + + + R + + + + + true + + + + :/icons/line.png:/icons/line.png + + + &Line Path Mode + + + P + + + + + + + + diff -r f81445a7abde -r a4b463a7ee82 src/messageLog.cpp --- a/src/messageLog.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/messageLog.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -20,7 +20,7 @@ #include #include "messageLog.h" #include "glRenderer.h" -#include "mainWindow.h" +#include "mainwindow.h" enum { diff -r f81445a7abde -r a4b463a7ee82 src/miscallenous.cpp --- a/src/miscallenous.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/miscallenous.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -21,7 +21,7 @@ #include #include "main.h" #include "miscallenous.h" -#include "mainWindow.h" +#include "mainwindow.h" #include "dialogs.h" #include "ldDocument.h" #include "ui_rotpoint.h" diff -r f81445a7abde -r a4b463a7ee82 src/partDownloader.cpp --- a/src/partDownloader.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/partDownloader.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -27,7 +27,7 @@ #include "partDownloader.h" #include "ui_downloadfrom.h" #include "basics.h" -#include "mainWindow.h" +#include "mainwindow.h" #include "ldDocument.h" #include "glRenderer.h" diff -r f81445a7abde -r a4b463a7ee82 src/primitives.cpp --- a/src/primitives.cpp Sun Aug 30 04:45:16 2015 +0300 +++ b/src/primitives.cpp Sun Aug 30 04:53:37 2015 +0300 @@ -20,7 +20,7 @@ #include #include #include "ldDocument.h" -#include "mainWindow.h" +#include "mainwindow.h" #include "primitives.h" #include "ui_makeprim.h" #include "miscallenous.h" diff -r f81445a7abde -r a4b463a7ee82 ui/ldforge.ui --- a/ui/ldforge.ui Sun Aug 30 04:45:16 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1713 +0,0 @@ - - - LDForgeUI - - - - 0 - 0 - 1010 - 641 - - - - - - - - :/icons/ldforge.png:/icons/ldforge.png - - - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - 0 - - - - - 0 - 0 - 234 - 402 - - - - Document - - - - - - - 0 - 0 - - - - QAbstractItemView::ExtendedSelection - - - - - - - - - 0 - 0 - 234 - 402 - - - - Tool Options - - - - - - Circle Tool Options - - - - - - - - High resolution - - - - - - - Segments: - - - - - - - - - true - - - 1 - - - 16 - - - 16 - - - - - - - a / b - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - 0 - 0 - 234 - 402 - - - - Primitives - - - - - - QAbstractItemView::DragOnly - - - false - - - - 1 - - - - - - - - - - - - - - - - 0 - 0 - 1010 - 30 - - - - - Fi&le - - - - Open &Recent... - - - - :/icons/open-recent.png:/icons/open-recent.png - - - - - - - - - - - - - - - - - - - - - - - - - - - &View - - - - - - - - - - - - - - - - - - - - I&nsert - - - - - - - - - - - - - - - Edit - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Tools - - - - - - - - - - - - - - - - - - - - - - - - - - - - - E&xternal Tools - - - - - - - - - - - Help - - - - - - - - - &Move - - - - &Grids - - - - - - - - &Move Objects - - - - - - - - - - - &Object List - - - - - - - &Rotate - - - - - - - - - - - - - - - - - - - - - - - - - - - - File - - - TopToolBarArea - - - false - - - - - - - - - - New Object - - - TopToolBarArea - - - false - - - - - - - - - - - - - Basic tools - - - TopToolBarArea - - - false - - - - - - - - - - - Select - - - TopToolBarArea - - - false - - - - - - - - Grid - - - TopToolBarArea - - - false - - - - - - - - Display options - - - TopToolBarArea - - - true - - - - - - - - - - Editing tools - - - TopToolBarArea - - - false - - - - - - - - - - - - - - - - - Editing modes - - - LeftToolBarArea - - - false - - - - - - - - - - - Colors - - - RightToolBarArea - - - false - - - - - External Programs - - - TopToolBarArea - - - false - - - - - - - - - - - - :/icons/brick.png:/icons/brick.png - - - &New Part - - - Create a new part model. - - - Ctrl+N - - - - - - :/icons/file-open.png:/icons/file-open.png - - - &Open - - - Load a part model from a file. - - - Ctrl+O - - - - - - :/icons/file-save.png:/icons/file-save.png - - - &Save - - - Save the part model. - - - - - - Ctrl+S - - - - - - :/icons/file-save-as.png:/icons/file-save-as.png - - - Sa&ve As.. - - - Save the part model to a specific file. - - - Ctrl+Shift+S - - - - - - :/icons/file-import.png:/icons/file-import.png - - - &Insert From.. - - - - - - :/icons/file-export.png:/icons/file-export.png - - - &Export To.. - - - - - - :/icons/settings.png:/icons/settings.png - - - Settin&gs - - - Edit the settings of LDForge. - - - - - - - - - :/icons/settings.png:/icons/settings.png - - - Set &LDraw Path - - - Change the LDraw directory path. - - - - - - :/icons/radial.png:/icons/radial.png - - - Scan &Primitives - - - Scan the primitives folder for primitive info. Use this if you add new primitives. - - - - - - :/icons/exit.png:/icons/exit.png - - - E&xit - - - Ctrl+Q - - - - - &Reset View - - - - - true - - - true - - - - :/icons/axes.png:/icons/axes.png - - - &Draw Axes - - - - - true - - - - :/icons/wireframe.png:/icons/wireframe.png - - - &Wireframe - - - - - true - - - - :/icons/bfc-view.png:/icons/bfc-view.png - - - &BFC Red/Green View - - - Shift+B - - - - - - :/icons/overlay.png:/icons/overlay.png - - - &Set Overlay Image - - - - - - :/icons/overlay-clear.png:/icons/overlay-clear.png - - - &Clear Overlay Image - - - - - - :/icons/screencap.png:/icons/screencap.png - - - Screens&hot - - - - - &LDraw Code.. - - - - - - :/icons/add-line.png:/icons/add-line.png - - - N&ew Line - - - - - - :/icons/add-subfile.png:/icons/add-subfile.png - - - &New Subfile Reference - - - - - - :/icons/add-triangle.png:/icons/add-triangle.png - - - Ne&w Triangle - - - - - - :/icons/add-quad.png:/icons/add-quad.png - - - New &Quadrilateral - - - - - - :/icons/add-condline.png:/icons/add-condline.png - - - New &Conditional Line - - - - - - :/icons/add-comment.png:/icons/add-comment.png - - - New C&omment - - - - - - :/icons/add-bfc.png:/icons/add-bfc.png - - - New &BFC Statement - - - - - - :/icons/add-vertex.png:/icons/add-vertex.png - - - New &Vertex - - - - - - :/icons/undo.png:/icons/undo.png - - - &Undo - - - Undo a step. - - - Ctrl+Z - - - - - - :/icons/redo.png:/icons/redo.png - - - &Redo - - - Redo a step. - - - Ctrl+Shift+Z - - - - - - :/icons/cut.png:/icons/cut.png - - - &Cut - - - Cut the current selection to clipboard. - - - Ctrl+X - - - - - - :/icons/copy.png:/icons/copy.png - - - C&opy - - - Copy the current selection to clipboard. - - - - - - Ctrl+C - - - - - - :/icons/paste.png:/icons/paste.png - - - &Paste - - - Paste clipboard contents. - - - Ctrl+V - - - - - - :/icons/delete.png:/icons/delete.png - - - &Delete - - - Delete the selection - - - Del - - - - - - :/icons/select-all.png:/icons/select-all.png - - - &Select All - - - Ctrl+A - - - - - - :/icons/select-color.png:/icons/select-color.png - - - Select &by Color - - - - - - :/icons/select-type.png:/icons/select-type.png - - - Select b&y Type - - - - - true - - - true - - - - :/icons/mode-select.png:/icons/mode-select.png - - - Select Mode - - - S - - - - - true - - - - :/icons/mode-draw.png:/icons/mode-draw.png - - - Dra&w Mode - - - D - - - - - Set Draw Dept&h - - - - - - :/icons/palette.png:/icons/palette.png - - - &Set Color - - - Set the color on given objects. - - - Shift+C - - - - - - :/icons/autocolor.png:/icons/autocolor.png - - - &Auto-color - - - Set the color of the given object to the first found unused color. - - - Ctrl+Shift+C - - - - - - :/icons/uncolorize.png:/icons/uncolorize.png - - - &Uncolor - - - Uncolor - - - Reduce colors of everything selected to main and edge colors - - - - - - :/icons/inline.png:/icons/inline.png - - - I&nline - - - Inline selected subfiles. - - - Ctrl+I - - - - - - :/icons/inline-deep.png:/icons/inline-deep.png - - - &Deep Inline - - - Recursively inline selected subfiles down to polygons only. - - - Ctrl+Shift+I - - - - - - :/icons/invert.png:/icons/invert.png - - - &Invert - - - Ctrl+Shift+W - - - - - - :/icons/radial.png:/icons/radial.png - - - &Generate Primitive - - - - - - :/icons/quad-split.png:/icons/quad-split.png - - - Split &Quads - - - Split quads into triangles. - - - - - - :/icons/set-contents.png:/icons/set-contents.png - - - &Edit LDraw Code - - - Edit the LDraw code of this object. - - - - - - :/icons/make-borders.png:/icons/make-borders.png - - - &Make Borders - - - Add borders around given polygons. - - - - - - :/icons/round-coords.png:/icons/round-coords.png - - - &Round Coordinates - - - Round coordinates down to 3/4 decimals - - - - - - :/icons/visibility-toggle.png:/icons/visibility-toggle.png - - - &Toggle Visibility - - - Toggles visibility/hiding on objects. - - - - - - :/icons/replace-coords.png:/icons/replace-coords.png - - - Re&place Coordinates - - - Find and replace coordinate values. - - - - - - :/icons/flip.png:/icons/flip.png - - - &Flip - - - Flip coordinates. - - - Ctrl+Shift+F - - - - - Demote Conditional Lines - - - Demote conditional lines down to normal lines. - - - - - - :/icons/ytruder.png:/icons/ytruder.png - - - &Ytruder - - - Extrude selected lines to a given plane - - - - - - :/icons/rectifier.png:/icons/rectifier.png - - - &Rectifier - - - Optimizes quads into rect primitives. - - - - - - :/icons/intersector.png:/icons/intersector.png - - - &Intersector - - - Perform clipping between two input groups. - - - - - - :/icons/isecalc.png:/icons/isecalc.png - - - I&secalc - - - Compute intersection edgelines between two input groups. - - - - - - :/icons/coverer.png:/icons/coverer.png - - - &Coverer - - - Fill the space between two line shapes - - - - - &Edger 2 - - - - - false - - - - :/icons/help.png:/icons/help.png - - - &Help - - - F1 - - - - - - :/icons/ldforge.png:/icons/ldforge.png - - - &About LDForge - - - - - About &Qt - - - - - true - - - - :/icons/grid-coarse.png:/icons/grid-coarse.png - - - &Coarse Grid - - - - - true - - - true - - - - :/icons/grid-medium.png:/icons/grid-medium.png - - - &Medium Grid - - - - - true - - - - :/icons/grid-fine.png:/icons/grid-fine.png - - - &Fine Grid - - - - - &Edit Selected Object - - - - - - :/icons/arrow-up.png:/icons/arrow-up.png - - - &Move Up - - - PgUp - - - - - - :/icons/arrow-down.png:/icons/arrow-down.png - - - Move &Down - - - PgDown - - - - - - :/icons/move-x-neg.png:/icons/move-x-neg.png - - - &Move -X - - - Left - - - - - - :/icons/move-x-pos.png:/icons/move-x-pos.png - - - Move +&X - - - Right - - - - - - :/icons/move-y-neg.png:/icons/move-y-neg.png - - - Move -&Y - - - Home - - - - - - :/icons/move-y-pos.png:/icons/move-y-pos.png - - - M&ove +Y - - - End - - - - - - :/icons/move-z-neg.png:/icons/move-z-neg.png - - - Move -&Z - - - Down - - - - - - :/icons/move-z-pos.png:/icons/move-z-pos.png - - - Mo&ve +Z - - - Up - - - - - &Rotate -X - - - Ctrl+Left - - - - - Rotate +&X - - - Ctrl+Right - - - - - Rotate -&Y - - - Ctrl+End - - - - - R&otate +Y - - - Ctrl+Home - - - - - Rotate -&Z - - - Ctrl+Down - - - - - Rotat&e +Z - - - Ctrl+Up - - - - - &Set Rotation Point - - - - - Save All - - - - - &Close - - - Ctrl+W - - - - - Close All - - - Ctrl+Shift+W - - - - - - :/icons/file-new.png:/icons/file-new.png - - - New &File - - - Ctrl+N - - - - - &Download From... - - - - - Add History Line - - - - - &Go to Line... - - - Ctrl+G - - - - - true - - - - :/icons/mode-circle.png:/icons/mode-circle.png - - - C&ircle Mode - - - C - - - - - - :/icons/visibility-hide.png:/icons/visibility-hide.png - - - &Hide - - - Hides objects from view - - - - - - :/icons/visibility-show.png:/icons/visibility-show.png - - - Re&veal - - - Reveals objects. Undoes hiding. - - - - - Subfile Selection - - - - - true - - - - :/icons/mode-angle.png:/icons/mode-angle.png - - - Draw An&gles - - - Draw angle information when drawing lines - - - - - true - - - - :/icons/random-colors.png:/icons/random-colors.png - - - Ra&ndom colors - - - Shift+R - - - - - &Open Subfiles for Editing - - - Opens the documents used by the selected subparts for editing. - - - - - Split &Lines... - - - - - true - - - Draw s&urfaces - - - Render surfaces (i.e. quads and triangles) on the viewport. - - - - - true - - - Draw &edgelines - - - Render edgelines on the viewport - - - - - true - - - Draw conditional &lines - - - Render conditional lines on the viewport. - - - - - true - - - - :/icons/mode-magicwand.png:/icons/mode-magicwand.png - - - &Magic wand - - - W - - - - - true - - - - :/icons/mode-rectangle.png:/icons/mode-rectangle.png - - - Recta&ngle Mode - - - R - - - - - true - - - - :/icons/line.png:/icons/line.png - - - &Line Path Mode - - - P - - - - - - - -