src/mainWindow.h

Sun, 07 Sep 2014 04:11:55 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sun, 07 Sep 2014 04:11:55 +0300
changeset 883
69b8adc9a669
parent 882
2f3cc8e045d5
child 899
eb9604e381e3
child 927
409b82a4765e
child 945
c310073e4f22
permissions
-rw-r--r--

- fixed: due to a shared pointer called via reference called dismiss() in LDDocument::closeInitialFile, this could cause LDDocuments to delete themselves in setImplicit(true) as no shared pointers were left inside closeInitialFile to keep the refcount up.
- fixed: bad QMap iteration after erase in the gl compiler

how diabolic can bugs get? *shudder*

/*
 *  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 <http://www.gnu.org/licenses/>.
 */

#pragma once
#include <functional>
#include <QMainWindow>
#include <QAction>
#include <QListWidget>
#include <QRadioButton>
#include "configuration.h"
#include "ldObject.h"
#include "ui_ldforge.h"
#include "colors.h"

class MessageManager;
class MainWindow;
class LDColorData;
class QToolButton;
class QDialogButtonBox;
class GLRenderer;
class QComboBox;
class QProgressBar;
class Ui_LDForgeUI;
class 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 (LDDocumentPtr 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 (LDDocumentPtr 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<LDQuickColor>& 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<void(QAction*)> 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_actionCornerVerts();
	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<LDQuickColor>	m_quickColors;
	QList<QToolButton*>	m_colorButtons;
	QList<QAction*>		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<LDQuickColor> 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<class T>
T RadioSwitch (const T& defval, QList<Pair<QRadioButton*, T>> haystack)
{
	for (Pair<QRadioButton*, const T&> 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<class T>
void RadioDefault (const T& expr, QList<Pair<QRadioButton*, T>> haystack)
{
	for (Pair<QRadioButton*, const T&> 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());

mercurial