Instance view, model, delegate.
This commit is contained in:
		| @@ -71,6 +71,10 @@ include_directories(${LIBSETTINGS_INCLUDE_DIR}) | |||||||
| add_subdirectory(libmultimc) | add_subdirectory(libmultimc) | ||||||
| include_directories(${LIBMULTIMC_INCLUDE_DIR}) | include_directories(${LIBMULTIMC_INCLUDE_DIR}) | ||||||
|  |  | ||||||
|  | # Add the group view library. | ||||||
|  | add_subdirectory(libgroupview) | ||||||
|  | include_directories(${LIBGROUPVIEW_INCLUDE_DIR}) | ||||||
|  |  | ||||||
| # Add the stdinstance plugin. | # Add the stdinstance plugin. | ||||||
| add_subdirectory(plugins/stdinstance) | add_subdirectory(plugins/stdinstance) | ||||||
|  |  | ||||||
| @@ -166,6 +170,8 @@ gui/taskdialog.h | |||||||
| gui/browserdialog.h | gui/browserdialog.h | ||||||
| gui/aboutdialog.h | gui/aboutdialog.h | ||||||
| gui/consolewindow.h | gui/consolewindow.h | ||||||
|  | gui/instancemodel.h | ||||||
|  | gui/instancedelegate.h | ||||||
|  |  | ||||||
| multimc_pragma.h | multimc_pragma.h | ||||||
|  |  | ||||||
| @@ -192,6 +198,8 @@ gui/taskdialog.cpp | |||||||
| gui/browserdialog.cpp | gui/browserdialog.cpp | ||||||
| gui/aboutdialog.cpp | gui/aboutdialog.cpp | ||||||
| gui/consolewindow.cpp | gui/consolewindow.cpp | ||||||
|  | gui/instancemodel.cpp | ||||||
|  | gui/instancedelegate.cpp | ||||||
|  |  | ||||||
| java/javautils.cpp | java/javautils.cpp | ||||||
| java/annotations.cpp | java/annotations.cpp | ||||||
| @@ -248,9 +256,9 @@ ADD_EXECUTABLE(MultiMC MACOSX_BUNDLE WIN32 | |||||||
| # Link | # Link | ||||||
| QT5_USE_MODULES(MultiMC Widgets Network WebKitWidgets) | QT5_USE_MODULES(MultiMC Widgets Network WebKitWidgets) | ||||||
| TARGET_LINK_LIBRARIES(MultiMC quazip patchlib  | TARGET_LINK_LIBRARIES(MultiMC quazip patchlib  | ||||||
| libUtil libSettings libMultiMC | libUtil libSettings libMultiMC libGroupView | ||||||
| ${MultiMC_LINK_ADDITIONAL_LIBS}) | ${MultiMC_LINK_ADDITIONAL_LIBS}) | ||||||
| ADD_DEPENDENCIES(MultiMC MultiMCLauncher libUtil libSettings libMultiMC) | ADD_DEPENDENCIES(MultiMC MultiMCLauncher libUtil libSettings libMultiMC libGroupView) | ||||||
|  |  | ||||||
|  |  | ||||||
| ################################ INSTALLATION AND PACKAGING ################################ | ################################ INSTALLATION AND PACKAGING ################################ | ||||||
|   | |||||||
							
								
								
									
										222
									
								
								gui/instancedelegate.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								gui/instancedelegate.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,222 @@ | |||||||
|  | #include "instancedelegate.h" | ||||||
|  | #include <QPainter> | ||||||
|  | #include <QTextOption> | ||||||
|  | #include <QTextLayout> | ||||||
|  | #include <QApplication> | ||||||
|  | #include <QtCore/qmath.h> | ||||||
|  |  | ||||||
|  | // Origin: Qt | ||||||
|  | static void viewItemTextLayout ( QTextLayout &textLayout, int lineWidth, qreal &height, qreal &widthUsed ) | ||||||
|  | { | ||||||
|  | 	height = 0; | ||||||
|  | 	widthUsed = 0; | ||||||
|  | 	textLayout.beginLayout(); | ||||||
|  | 	while ( true ) | ||||||
|  | 	{ | ||||||
|  | 		QTextLine line = textLayout.createLine(); | ||||||
|  | 		if ( !line.isValid() ) | ||||||
|  | 			break; | ||||||
|  | 		line.setLineWidth ( lineWidth ); | ||||||
|  | 		line.setPosition ( QPointF ( 0, height ) ); | ||||||
|  | 		height += line.height(); | ||||||
|  | 		widthUsed = qMax ( widthUsed, line.naturalTextWidth() ); | ||||||
|  | 	} | ||||||
|  | 	textLayout.endLayout(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #define QFIXED_MAX (INT_MAX/256) | ||||||
|  |  | ||||||
|  | ListViewDelegate::ListViewDelegate ( QObject* parent ) : QStyledItemDelegate ( parent ) | ||||||
|  | { | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void drawSelectionRect(QPainter *painter, const QStyleOptionViewItemV4 &option, const QRect &rect) | ||||||
|  | { | ||||||
|  | 	if (!(option.state & QStyle::State_Selected)) | ||||||
|  | 		return; | ||||||
|  | 	painter->fillRect ( rect, option.palette.brush ( QPalette::Highlight ) ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void drawFocusRect(QPainter *painter, const QStyleOptionViewItemV4 &option, const QRect &rect) | ||||||
|  | { | ||||||
|  | 	if (!(option.state & QStyle::State_HasFocus)) | ||||||
|  | 		return; | ||||||
|  | 	QStyleOptionFocusRect opt; | ||||||
|  | 	opt.direction       = option.direction; | ||||||
|  | 	opt.fontMetrics     = option.fontMetrics; | ||||||
|  | 	opt.palette         = option.palette; | ||||||
|  | 	opt.rect            = rect; | ||||||
|  | 	//opt.state           = option.state | QStyle::State_KeyboardFocusChange | QStyle::State_Item; | ||||||
|  | 	auto col = option.state & QStyle::State_Selected ? QPalette::Highlight : QPalette::Base; | ||||||
|  | 	opt.backgroundColor = option.palette.color(col); | ||||||
|  | 	// Apparently some widget styles expect this hint to not be set | ||||||
|  | 	painter->setRenderHint(QPainter::Antialiasing, false); | ||||||
|  |  | ||||||
|  | 	QStyle *style = option.widget ? option.widget->style() : QApplication::style(); | ||||||
|  |  | ||||||
|  | 	style->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, painter, option.widget); | ||||||
|  |  | ||||||
|  | 	painter->setRenderHint(QPainter::Antialiasing); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static QSize viewItemTextSize ( const QStyleOptionViewItemV4 *option ) | ||||||
|  | { | ||||||
|  | 	QStyle *style = option->widget ? option->widget->style() : QApplication::style(); | ||||||
|  | 	QTextOption textOption; | ||||||
|  | 	textOption.setWrapMode ( QTextOption::WrapAtWordBoundaryOrAnywhere ); | ||||||
|  | 	QTextLayout textLayout; | ||||||
|  | 	textLayout.setTextOption ( textOption ); | ||||||
|  | 	textLayout.setFont ( option->font ); | ||||||
|  | 	textLayout.setText ( option->text ); | ||||||
|  | 	const int textMargin = style->pixelMetric ( QStyle::PM_FocusFrameHMargin, option, option->widget ) + 1; | ||||||
|  | 	QRect bounds ( 0,0,100 - 2*textMargin,600 ); | ||||||
|  | 	qreal height = 0, widthUsed = 0; | ||||||
|  | 	viewItemTextLayout ( textLayout, bounds.width(), height, widthUsed ); | ||||||
|  | 	const QSize size ( qCeil ( widthUsed ), qCeil ( height ) ); | ||||||
|  | 	return QSize ( size.width() + 2 * textMargin, size.height() ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ListViewDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const | ||||||
|  | { | ||||||
|  | 	QStyleOptionViewItemV4 opt = option; | ||||||
|  | 	initStyleOption ( &opt, index ); | ||||||
|  | 	painter->save(); | ||||||
|  | 	painter->setClipRect ( opt.rect ); | ||||||
|  |  | ||||||
|  | 	opt.features |= QStyleOptionViewItem::WrapText; | ||||||
|  | 	opt.text = index.data().toString(); | ||||||
|  | 	opt.textElideMode = Qt::ElideRight; | ||||||
|  | 	opt.displayAlignment = Qt::AlignTop | Qt::AlignHCenter; | ||||||
|  |  | ||||||
|  | 	QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); | ||||||
|  |  | ||||||
|  | 	//const int iconSize =  style->pixelMetric(QStyle::PM_IconViewIconSize); | ||||||
|  | 	const int iconSize = 48; | ||||||
|  | 	QRect iconbox = opt.rect; | ||||||
|  | 	const int textMargin = style->pixelMetric ( QStyle::PM_FocusFrameHMargin, 0, opt.widget ) + 1; | ||||||
|  | 	QRect textRect = opt.rect; | ||||||
|  | 	QRect textHighlightRect = textRect; | ||||||
|  | 	// clip the decoration on top, remove width padding | ||||||
|  | 	textRect.adjust ( textMargin,iconSize + textMargin + 5,-textMargin,0 ); | ||||||
|  | 	 | ||||||
|  | 	textHighlightRect.adjust ( 0,iconSize + 5,0,0 ); | ||||||
|  |  | ||||||
|  | 	// draw background | ||||||
|  | 	{ | ||||||
|  | 		QSize textSize = viewItemTextSize ( &opt ); | ||||||
|  | 		QPalette::ColorGroup cg; | ||||||
|  | 		QStyleOptionViewItemV4 opt2(opt); | ||||||
|  | 		 | ||||||
|  | 		if((opt.widget && opt.widget->isEnabled()) || (opt.state & QStyle::State_Enabled)) | ||||||
|  | 		{ | ||||||
|  | 			if(! ( opt.state & QStyle::State_Active )) | ||||||
|  | 				cg = QPalette::Inactive; | ||||||
|  | 			else | ||||||
|  | 				cg = QPalette::Normal; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			cg = QPalette::Disabled; | ||||||
|  | 		} | ||||||
|  | 		opt2.palette.setCurrentColorGroup(cg); | ||||||
|  | 		 | ||||||
|  | 		// fill in background, if any | ||||||
|  | 		if ( opt.backgroundBrush.style() != Qt::NoBrush ) | ||||||
|  | 		{ | ||||||
|  | 			QPointF oldBO = painter->brushOrigin(); | ||||||
|  | 			painter->setBrushOrigin ( opt.rect.topLeft() ); | ||||||
|  | 			painter->fillRect ( opt.rect, opt.backgroundBrush ); | ||||||
|  | 			painter->setBrushOrigin ( oldBO ); | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
|  | 		if ( opt.showDecorationSelected ) | ||||||
|  | 		{ | ||||||
|  | 			drawSelectionRect(painter,opt2, opt.rect); | ||||||
|  | 			drawFocusRect(painter,opt2, opt.rect); | ||||||
|  | 			//painter->fillRect ( opt.rect, opt.palette.brush ( cg, QPalette::Highlight ) ); | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			 | ||||||
|  | 			//if ( opt.state & QStyle::State_Selected ) | ||||||
|  | 			{ | ||||||
|  | 				//QRect textRect = subElementRect ( QStyle::SE_ItemViewItemText,  opt, opt.widget ); | ||||||
|  | 				//painter->fillRect ( textHighlightRect, opt.palette.brush ( cg, QPalette::Highlight ) ); | ||||||
|  | 				drawSelectionRect(painter,opt2, textHighlightRect); | ||||||
|  | 				drawFocusRect(painter,opt2, textHighlightRect); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// draw the icon | ||||||
|  | 	{ | ||||||
|  | 		QIcon::Mode mode = QIcon::Normal; | ||||||
|  | 		if ( ! ( opt.state & QStyle::State_Enabled ) ) | ||||||
|  | 			mode = QIcon::Disabled; | ||||||
|  | 		else if ( opt.state & QStyle::State_Selected ) | ||||||
|  | 			mode = QIcon::Selected; | ||||||
|  | 		QIcon::State state = opt.state & QStyle::State_Open ? QIcon::On : QIcon::Off; | ||||||
|  |  | ||||||
|  | 		iconbox.setHeight ( iconSize ); | ||||||
|  | 		opt.icon.paint ( painter, iconbox, Qt::AlignCenter, mode, state ); | ||||||
|  | 	} | ||||||
|  | 	// set the text colors | ||||||
|  | 	QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; | ||||||
|  | 	if ( cg == QPalette::Normal && ! ( opt.state & QStyle::State_Active ) ) | ||||||
|  | 		cg = QPalette::Inactive; | ||||||
|  | 	if ( opt.state & QStyle::State_Selected ) | ||||||
|  | 	{ | ||||||
|  | 		painter->setPen ( opt.palette.color ( cg, QPalette::HighlightedText ) ); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		painter->setPen ( opt.palette.color ( cg, QPalette::Text ) ); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// draw the text | ||||||
|  | 	QTextOption textOption; | ||||||
|  | 	textOption.setWrapMode ( QTextOption::WrapAtWordBoundaryOrAnywhere ); | ||||||
|  | 	textOption.setTextDirection ( opt.direction ); | ||||||
|  | 	textOption.setAlignment ( QStyle::visualAlignment ( opt.direction, opt.displayAlignment ) ); | ||||||
|  | 	QTextLayout textLayout; | ||||||
|  | 	textLayout.setTextOption ( textOption ); | ||||||
|  | 	textLayout.setFont ( opt.font ); | ||||||
|  | 	textLayout.setText ( opt.text ); | ||||||
|  |  | ||||||
|  | 	qreal width, height; | ||||||
|  | 	viewItemTextLayout ( textLayout, iconbox.width(), height, width ); | ||||||
|  |  | ||||||
|  | 	const int lineCount = textLayout.lineCount(); | ||||||
|  |  | ||||||
|  | 	const QRect layoutRect = QStyle::alignedRect ( opt.direction, opt.displayAlignment, QSize ( iconbox.width(), int ( height ) ), textRect ); | ||||||
|  | 	const QPointF position = layoutRect.topLeft(); | ||||||
|  | 	for ( int i = 0; i < lineCount; ++i ) | ||||||
|  | 	{ | ||||||
|  | 		const QTextLine line = textLayout.lineAt ( i ); | ||||||
|  | 		line.draw ( painter, position ); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	painter->restore(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | QSize ListViewDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const | ||||||
|  | { | ||||||
|  | 	QStyleOptionViewItemV4 opt = option; | ||||||
|  | 	initStyleOption ( &opt, index ); | ||||||
|  | 	opt.features |= QStyleOptionViewItem::WrapText; | ||||||
|  | 	opt.text = index.data().toString(); | ||||||
|  | 	opt.textElideMode = Qt::ElideRight; | ||||||
|  | 	opt.displayAlignment = Qt::AlignTop | Qt::AlignHCenter; | ||||||
|  |  | ||||||
|  | 	QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); | ||||||
|  | 	const int textMargin = style->pixelMetric ( QStyle::PM_FocusFrameHMargin, &option, opt.widget ) + 1; | ||||||
|  | 	int height = 48 + textMargin * 2 + 5; // TODO: turn constants into variables | ||||||
|  | 	QSize szz = viewItemTextSize ( &opt ); | ||||||
|  | 	height += szz.height(); | ||||||
|  | 	// FIXME: maybe the icon items could scale and keep proportions? | ||||||
|  | 	QSize sz ( 100,height ); | ||||||
|  | 	return sz; | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								gui/instancedelegate.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								gui/instancedelegate.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <QStyledItemDelegate> | ||||||
|  |  | ||||||
|  | class ListViewDelegate : public QStyledItemDelegate | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	explicit ListViewDelegate ( QObject* parent = 0 ); | ||||||
|  | protected: | ||||||
|  | 	void paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; | ||||||
|  | 	QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const; | ||||||
|  | }; | ||||||
							
								
								
									
										92
									
								
								gui/instancemodel.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								gui/instancemodel.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | |||||||
|  | #include "instancemodel.h" | ||||||
|  | #include <instance.h> | ||||||
|  | #include <QIcon> | ||||||
|  |  | ||||||
|  | InstanceModel::InstanceModel ( const InstanceList& instances, QObject *parent ) | ||||||
|  | 	: QAbstractListModel ( parent ), m_instances ( &instances ) | ||||||
|  | { | ||||||
|  | 	cachedIcon = QIcon(":/icons/multimc/scalable/apps/multimc.svg"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int InstanceModel::rowCount ( const QModelIndex& parent ) const | ||||||
|  | { | ||||||
|  | 	Q_UNUSED ( parent ); | ||||||
|  | 	return m_instances->count(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QModelIndex InstanceModel::index ( int row, int column, const QModelIndex& parent ) const | ||||||
|  | { | ||||||
|  | 	Q_UNUSED ( parent ); | ||||||
|  | 	if ( row < 0 || row >= m_instances->count() ) | ||||||
|  | 		return QModelIndex(); | ||||||
|  | 	return createIndex ( row, column, ( void* ) m_instances->at ( row ).data() ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QVariant InstanceModel::data ( const QModelIndex& index, int role ) const | ||||||
|  | { | ||||||
|  | 	if ( !index.isValid() ) | ||||||
|  | 	{ | ||||||
|  | 		return QVariant(); | ||||||
|  | 	} | ||||||
|  | 	Instance *pdata = static_cast<Instance*> ( index.internalPointer() ); | ||||||
|  | 	switch ( role ) | ||||||
|  | 	{ | ||||||
|  | 	case InstancePointerRole: | ||||||
|  | 	{ | ||||||
|  | 		QVariant v = qVariantFromValue((void *) pdata); | ||||||
|  | 		return v; | ||||||
|  | 	} | ||||||
|  | 	case Qt::DisplayRole: | ||||||
|  | 	{ | ||||||
|  | 		return pdata->name(); | ||||||
|  | 	} | ||||||
|  | 	case Qt::ToolTipRole: | ||||||
|  | 	{ | ||||||
|  | 		return pdata->rootDir(); | ||||||
|  | 	} | ||||||
|  | 	case Qt::DecorationRole: | ||||||
|  | 	{ | ||||||
|  | 		// FIXME: replace with an icon cache | ||||||
|  | 		return cachedIcon; | ||||||
|  | 	} | ||||||
|  | 	// for now. | ||||||
|  | 	case KCategorizedSortFilterProxyModel::CategorySortRole: | ||||||
|  | 	case KCategorizedSortFilterProxyModel::CategoryDisplayRole: | ||||||
|  | 	{ | ||||||
|  | 		return "IT'S A GROUP"; | ||||||
|  | 	} | ||||||
|  | 	default: | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | 	return QVariant(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Qt::ItemFlags InstanceModel::flags ( const QModelIndex& index ) const | ||||||
|  | { | ||||||
|  | 	Qt::ItemFlags f; | ||||||
|  | 	if ( index.isValid() ) | ||||||
|  | 	{ | ||||||
|  | 		f |= ( Qt::ItemIsEnabled | Qt::ItemIsSelectable ); | ||||||
|  | 	} | ||||||
|  | 	return f; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | InstanceProxyModel::InstanceProxyModel ( QObject *parent ) | ||||||
|  | 	: KCategorizedSortFilterProxyModel ( parent ) | ||||||
|  | { | ||||||
|  | 	// disable since by default we are globally sorting by date: | ||||||
|  | 	setCategorizedModel(true); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool InstanceProxyModel::subSortLessThan ( | ||||||
|  |  const QModelIndex& left, const QModelIndex& right ) const | ||||||
|  | { | ||||||
|  | 	Instance *pdataLeft = static_cast<Instance*> ( left.internalPointer() ); | ||||||
|  | 	Instance *pdataRight = static_cast<Instance*> ( right.internalPointer() ); | ||||||
|  | 	//kDebug() << *pdataLeft << *pdataRight; | ||||||
|  | 	return QString::localeAwareCompare(pdataLeft->name(), pdataRight->name()) < 0; | ||||||
|  | 	//return pdataLeft->name() < pdataRight->name(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #include "instancemodel.moc" | ||||||
|  |  | ||||||
							
								
								
									
										38
									
								
								gui/instancemodel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								gui/instancemodel.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <QAbstractListModel> | ||||||
|  | #include "kcategorizedsortfilterproxymodel.h" | ||||||
|  | #include "instancelist.h" | ||||||
|  | #include <QIcon> | ||||||
|  |  | ||||||
|  | class InstanceModel : public QAbstractListModel | ||||||
|  | { | ||||||
|  | 	Q_OBJECT | ||||||
|  | public: | ||||||
|  | 	enum AdditionalRoles | ||||||
|  | 	{ | ||||||
|  | 		InstancePointerRole = 0x34B1CB48 ///< Return pointer to real instance | ||||||
|  | 	}; | ||||||
|  | 	explicit InstanceModel ( const InstanceList& instances, | ||||||
|  | 	                         QObject *parent = 0 ); | ||||||
|  |  | ||||||
|  | 	QModelIndex  index ( int row, int column = 0, | ||||||
|  | 	                     const QModelIndex& parent = QModelIndex() ) const; | ||||||
|  | 	int rowCount ( const QModelIndex& parent = QModelIndex() ) const; | ||||||
|  | 	QVariant data ( const QModelIndex& index, int role ) const; | ||||||
|  | 	Qt::ItemFlags flags ( const QModelIndex& index ) const; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	const InstanceList* m_instances; | ||||||
|  | 	QIcon cachedIcon; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class InstanceProxyModel : public KCategorizedSortFilterProxyModel | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	explicit InstanceProxyModel ( QObject *parent = 0 ); | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  | 	virtual bool subSortLessThan ( const QModelIndex& left, const QModelIndex& right ) const; | ||||||
|  | }; | ||||||
|  |  | ||||||
| @@ -40,45 +40,94 @@ | |||||||
| #include "gui/browserdialog.h" | #include "gui/browserdialog.h" | ||||||
| #include "gui/aboutdialog.h" | #include "gui/aboutdialog.h" | ||||||
|  |  | ||||||
|  | #include "kcategorizedview.h" | ||||||
|  | #include "kcategorydrawer.h" | ||||||
|  |  | ||||||
| #include "instancelist.h" | #include "instancelist.h" | ||||||
| #include "appsettings.h" | #include "appsettings.h" | ||||||
| #include "version.h" | #include "version.h" | ||||||
|  |  | ||||||
| #include "logintask.h" | #include "logintask.h" | ||||||
|  | #include <instance.h> | ||||||
|  |  | ||||||
|  | #include "instancemodel.h" | ||||||
|  | #include "instancedelegate.h" | ||||||
|  |  | ||||||
| // Opens the given file in the default application. | // Opens the given file in the default application. | ||||||
| // TODO: Move this somewhere. | // TODO: Move this somewhere. | ||||||
| void openInDefaultProgram(QString filename); | void openInDefaultProgram ( QString filename ); | ||||||
|  |  | ||||||
| MainWindow::MainWindow(QWidget *parent) : | MainWindow::MainWindow ( QWidget *parent ) : | ||||||
| 	QMainWindow(parent), | 	QMainWindow ( parent ), | ||||||
| 	ui(new Ui::MainWindow), | 	ui ( new Ui::MainWindow ), | ||||||
| 	instList(globalSettings->get("InstanceDir").toString()) | 	instList ( globalSettings->get ( "InstanceDir" ).toString() ) | ||||||
| { | { | ||||||
| 	ui->setupUi(this); | 	ui->setupUi ( this ); | ||||||
|  | 	// Create the widget | ||||||
|  | 	instList.loadList(); | ||||||
| 	 | 	 | ||||||
| 	setWindowTitle(QString("MultiMC %1").arg(Version::current.toString())); | 	view = new KCategorizedView ( ui->centralWidget ); | ||||||
|  | 	drawer = new KCategoryDrawer ( view ); | ||||||
|  |  | ||||||
|  | 	view->setSelectionMode ( QAbstractItemView::SingleSelection ); | ||||||
|  | 	//view->setSpacing( KDialog::spacingHint() ); | ||||||
|  | 	view->setCategoryDrawer ( drawer ); | ||||||
|  | 	view->setCollapsibleBlocks ( true ); | ||||||
|  | 	view->setViewMode ( QListView::IconMode ); | ||||||
|  | 	view->setFlow ( QListView::LeftToRight ); | ||||||
|  | 	view->setWordWrap(true); | ||||||
|  | 	view->setMouseTracking ( true ); | ||||||
|  | 	view->viewport()->setAttribute ( Qt::WA_Hover ); | ||||||
|  | 	auto delegate = new ListViewDelegate(); | ||||||
|  | 	view->setItemDelegate(delegate); | ||||||
|  | 	view->setSpacing(10); | ||||||
|  |  | ||||||
|  | 	model = new InstanceModel ( instList,this ); | ||||||
|  | 	proxymodel = new InstanceProxyModel ( this ); | ||||||
|  | 	proxymodel->setSortRole ( KCategorizedSortFilterProxyModel::CategorySortRole ); | ||||||
|  | 	proxymodel->setFilterRole ( KCategorizedSortFilterProxyModel::CategorySortRole ); | ||||||
|  | 	//proxymodel->setDynamicSortFilter ( true ); | ||||||
|  | 	proxymodel->setSourceModel ( model ); | ||||||
|  | 	proxymodel->sort ( 0 ); | ||||||
|  |  | ||||||
|  | 	view->setFrameShape ( QFrame::NoFrame ); | ||||||
|  |  | ||||||
|  | 	ui->horizontalLayout->addWidget ( view ); | ||||||
|  | 	setWindowTitle ( QString ( "MultiMC %1" ).arg ( Version::current.toString() ) ); | ||||||
| 	// TODO: Make this work with the new settings system. | 	// TODO: Make this work with the new settings system. | ||||||
| //	restoreGeometry(settings->getConfig().value("MainWindowGeometry", saveGeometry()).toByteArray()); | //	restoreGeometry(settings->getConfig().value("MainWindowGeometry", saveGeometry()).toByteArray()); | ||||||
| //	restoreState(settings->getConfig().value("MainWindowState", saveState()).toByteArray()); | //	restoreState(settings->getConfig().value("MainWindowState", saveState()).toByteArray()); | ||||||
|  | 	view->setModel ( proxymodel ); | ||||||
|  | 	connect(view, SIGNAL(doubleClicked(const QModelIndex &)), | ||||||
|  |         this, SLOT(instanceActivated(const QModelIndex &))); | ||||||
|  |  | ||||||
| 	instList.loadList(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| MainWindow::~MainWindow() | MainWindow::~MainWindow() | ||||||
| { | { | ||||||
| 	delete ui; | 	delete ui; | ||||||
|  | 	delete proxymodel; | ||||||
|  | 	delete model; | ||||||
|  | 	delete drawer; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void MainWindow::instanceActivated ( QModelIndex index ) | ||||||
|  | { | ||||||
|  | 	if(!index.isValid()) | ||||||
|  | 		return; | ||||||
|  | 	Instance * inst = (Instance *) index.data(InstanceModel::InstancePointerRole).value<void *>(); | ||||||
|  | 	doLogin(inst->id()); | ||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::on_actionAddInstance_triggered() | void MainWindow::on_actionAddInstance_triggered() | ||||||
| { | { | ||||||
| 	NewInstanceDialog *newInstDlg = new NewInstanceDialog(this); | 	NewInstanceDialog *newInstDlg = new NewInstanceDialog ( this ); | ||||||
| 	newInstDlg->exec(); | 	newInstDlg->exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::on_actionViewInstanceFolder_triggered() | void MainWindow::on_actionViewInstanceFolder_triggered() | ||||||
| { | { | ||||||
| 	openInDefaultProgram(globalSettings->get("InstanceDir").toString()); | 	openInDefaultProgram ( globalSettings->get ( "InstanceDir" ).toString() ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::on_actionRefresh_triggered() | void MainWindow::on_actionRefresh_triggered() | ||||||
| @@ -88,7 +137,7 @@ void MainWindow::on_actionRefresh_triggered() | |||||||
|  |  | ||||||
| void MainWindow::on_actionViewCentralModsFolder_triggered() | void MainWindow::on_actionViewCentralModsFolder_triggered() | ||||||
| { | { | ||||||
| 	openInDefaultProgram(globalSettings->get("CentralModsDir").toString()); | 	openInDefaultProgram ( globalSettings->get ( "CentralModsDir" ).toString() ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::on_actionCheckUpdate_triggered() | void MainWindow::on_actionCheckUpdate_triggered() | ||||||
| @@ -98,105 +147,116 @@ void MainWindow::on_actionCheckUpdate_triggered() | |||||||
|  |  | ||||||
| void MainWindow::on_actionSettings_triggered() | void MainWindow::on_actionSettings_triggered() | ||||||
| { | { | ||||||
| 	SettingsDialog dialog(this); | 	SettingsDialog dialog ( this ); | ||||||
| 	dialog.exec(); | 	dialog.exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::on_actionReportBug_triggered() | void MainWindow::on_actionReportBug_triggered() | ||||||
| { | { | ||||||
|     //QDesktopServices::openUrl(QUrl("http://bugs.forkk.net/")); | 	//QDesktopServices::openUrl(QUrl("http://bugs.forkk.net/")); | ||||||
|     openWebPage(QUrl("http://bugs.forkk.net/")); | 	openWebPage ( QUrl ( "http://bugs.forkk.net/" ) ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::on_actionNews_triggered() | void MainWindow::on_actionNews_triggered() | ||||||
| { | { | ||||||
|     //QDesktopServices::openUrl(QUrl("http://news.forkk.net/")); | 	//QDesktopServices::openUrl(QUrl("http://news.forkk.net/")); | ||||||
|     openWebPage(QUrl("http://news.forkk.net/")); | 	openWebPage ( QUrl ( "http://news.forkk.net/" ) ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::on_actionAbout_triggered() | void MainWindow::on_actionAbout_triggered() | ||||||
| { | { | ||||||
|     AboutDialog dialog(this); | 	AboutDialog dialog ( this ); | ||||||
|     dialog.exec(); | 	dialog.exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::on_mainToolBar_visibilityChanged(bool) | void MainWindow::on_mainToolBar_visibilityChanged ( bool ) | ||||||
| { | { | ||||||
| 	// Don't allow hiding the main toolbar. | 	// Don't allow hiding the main toolbar. | ||||||
| 	// This is the only way I could find to prevent it... :/ | 	// This is the only way I could find to prevent it... :/ | ||||||
| 	ui->mainToolBar->setVisible(true); | 	ui->mainToolBar->setVisible ( true ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::closeEvent(QCloseEvent *event) | void MainWindow::closeEvent ( QCloseEvent *event ) | ||||||
| { | { | ||||||
| 	// Save the window state and geometry. | 	// Save the window state and geometry. | ||||||
| 	// TODO: Make this work with the new settings system. | 	// TODO: Make this work with the new settings system. | ||||||
| //	settings->getConfig().setValue("MainWindowGeometry", saveGeometry()); | //	settings->getConfig().setValue("MainWindowGeometry", saveGeometry()); | ||||||
| //	settings->getConfig().setValue("MainWindowState", saveState()); | //	settings->getConfig().setValue("MainWindowState", saveState()); | ||||||
| 	QMainWindow::closeEvent(event); | 	QMainWindow::closeEvent ( event ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::on_instanceView_customContextMenuRequested(const QPoint &pos) | void MainWindow::on_instanceView_customContextMenuRequested ( const QPoint &pos ) | ||||||
| { | { | ||||||
| 	QMenu *instContextMenu = new QMenu("Instance", this); | 	QMenu *instContextMenu = new QMenu ( "Instance", this ); | ||||||
|  |  | ||||||
| 	// Add the actions from the toolbar to the context menu. | 	// Add the actions from the toolbar to the context menu. | ||||||
| 	instContextMenu->addActions(ui->instanceToolBar->actions()); | 	instContextMenu->addActions ( ui->instanceToolBar->actions() ); | ||||||
|  |  | ||||||
| 	instContextMenu->exec(ui->instanceView->mapToGlobal(pos)); | 	instContextMenu->exec ( view->mapToGlobal ( pos ) ); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void MainWindow::on_actionLaunchInstance_triggered() | void MainWindow::on_actionLaunchInstance_triggered() | ||||||
| { | { | ||||||
| 	doLogin(); | 	QModelIndex index = view->currentIndex(); | ||||||
| } | 	if(index.isValid()) | ||||||
|  |  | ||||||
| void MainWindow::doLogin(const QString &errorMsg) |  | ||||||
| { |  | ||||||
| 	LoginDialog* loginDlg = new LoginDialog(this, errorMsg); |  | ||||||
| 	if (loginDlg->exec()) |  | ||||||
| 	{ | 	{ | ||||||
| 		UserInfo uInfo(loginDlg->getUsername(), loginDlg->getPassword()); | 		Instance * inst = (Instance *) index.data(InstanceModel::InstancePointerRole).value<void *>(); | ||||||
| 		 | 		doLogin(inst->id()); | ||||||
| 		TaskDialog* tDialog = new TaskDialog(this); |  | ||||||
| 		LoginTask* loginTask = new LoginTask(uInfo, tDialog); |  | ||||||
| 		connect(loginTask, SIGNAL(loginComplete(LoginResponse)), |  | ||||||
| 				SLOT(onLoginComplete(LoginResponse)), Qt::QueuedConnection); |  | ||||||
| 		connect(loginTask, SIGNAL(loginFailed(QString)), |  | ||||||
| 				SLOT(doLogin(QString)), Qt::QueuedConnection); |  | ||||||
| 		tDialog->exec(loginTask); |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::onLoginComplete(LoginResponse response) | void MainWindow::doLogin ( QString inst, const QString& errorMsg ) | ||||||
| { | { | ||||||
| 	QMessageBox::information(this, "Login Successful",  | 	LoginDialog* loginDlg = new LoginDialog ( this, errorMsg ); | ||||||
| 							 QString("Logged in as %1 with session ID %2."). | 	if ( loginDlg->exec() ) | ||||||
| 							 arg(response.username(), response.sessionID())); | 	{ | ||||||
|  | 		UserInfo uInfo ( loginDlg->getUsername(), loginDlg->getPassword() ); | ||||||
|  |  | ||||||
|  | 		TaskDialog* tDialog = new TaskDialog ( this ); | ||||||
|  | 		LoginTask* loginTask = new LoginTask ( uInfo, inst, tDialog ); | ||||||
|  | 		connect ( loginTask, SIGNAL ( loginComplete ( QString, LoginResponse ) ), | ||||||
|  | 		          SLOT ( onLoginComplete ( QString, LoginResponse ) ), Qt::QueuedConnection ); | ||||||
|  | 		connect ( loginTask, SIGNAL ( loginFailed ( QString, QString ) ), | ||||||
|  | 		          SLOT ( onLoginFailed( QString, QString ) ), Qt::QueuedConnection ); | ||||||
|  | 		tDialog->exec ( loginTask ); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void MainWindow::onLoginComplete ( QString inst, LoginResponse response ) | ||||||
|  | { | ||||||
|  | 	QMessageBox::information ( this, "Login Successful", | ||||||
|  | 	                           QString ( "Logged in as %1 with session ID %2. Instance: %3" ). | ||||||
|  | 	                           arg ( response.username(), response.sessionID(), inst ) ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void MainWindow::onLoginFailed ( QString inst, const QString& errorMsg ) | ||||||
|  | { | ||||||
|  | 	doLogin(inst, errorMsg); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| // Create A Desktop Shortcut | // Create A Desktop Shortcut | ||||||
| void MainWindow::on_actionMakeDesktopShortcut_triggered() | void MainWindow::on_actionMakeDesktopShortcut_triggered() | ||||||
| { | { | ||||||
|     QString name("Test"); | 	QString name ( "Test" ); | ||||||
|     name = QInputDialog::getText(this, tr("MultiMC Shortcut"), tr("Enter a Shortcut Name."), QLineEdit::Normal, name); | 	name = QInputDialog::getText ( this, tr ( "MultiMC Shortcut" ), tr ( "Enter a Shortcut Name." ), QLineEdit::Normal, name ); | ||||||
|  |  | ||||||
|     Util::createShortCut(Util::getDesktopDir(), QApplication::instance()->applicationFilePath(), QStringList() << "-dl" << QDir::currentPath() << "test", name, "application-x-octet-stream"); | 	Util::createShortCut ( Util::getDesktopDir(), QApplication::instance()->applicationFilePath(), QStringList() << "-dl" << QDir::currentPath() << "test", name, "application-x-octet-stream" ); | ||||||
|  |  | ||||||
|     QMessageBox::warning(this, "Not useful", "A Dummy Shortcut was created. it will not do anything productive"); | 	QMessageBox::warning ( this, "Not useful", "A Dummy Shortcut was created. it will not do anything productive" ); | ||||||
| } | } | ||||||
|  |  | ||||||
| // BrowserDialog | // BrowserDialog | ||||||
| void MainWindow::openWebPage(QUrl url) | void MainWindow::openWebPage ( QUrl url ) | ||||||
| { | { | ||||||
|     BrowserDialog *browser = new BrowserDialog(this); | 	BrowserDialog *browser = new BrowserDialog ( this ); | ||||||
|  |  | ||||||
|     browser->load(url); | 	browser->load ( url ); | ||||||
|     browser->exec(); | 	browser->exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void openInDefaultProgram(QString filename) | void openInDefaultProgram ( QString filename ) | ||||||
| { | { | ||||||
| 	QDesktopServices::openUrl("file:///" + QFileInfo(filename).absolutePath()); | 	QDesktopServices::openUrl ( "file:///" + QFileInfo ( filename ).absolutePath() ); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -20,6 +20,12 @@ | |||||||
|  |  | ||||||
| #include "instancelist.h" | #include "instancelist.h" | ||||||
| #include "loginresponse.h" | #include "loginresponse.h" | ||||||
|  | #include "instance.h" | ||||||
|  |  | ||||||
|  | class InstanceModel; | ||||||
|  | class InstanceProxyModel; | ||||||
|  | class KCategorizedView; | ||||||
|  | class KCategoryDrawer; | ||||||
|  |  | ||||||
| namespace Ui | namespace Ui | ||||||
| { | { | ||||||
| @@ -67,14 +73,21 @@ private slots: | |||||||
|  |  | ||||||
|     void on_actionMakeDesktopShortcut_triggered(); |     void on_actionMakeDesktopShortcut_triggered(); | ||||||
| 	 | 	 | ||||||
| 	void doLogin(const QString& errorMsg = ""); | 	void doLogin( QString inst, const QString& errorMsg = "" ); | ||||||
| 	 | 	 | ||||||
| 	 | 	 | ||||||
| 	void onLoginComplete(LoginResponse response); | 	void onLoginComplete( QString inst, LoginResponse response ); | ||||||
|  | 	void onLoginFailed( QString inst, const QString& errorMsg ); | ||||||
|  |  | ||||||
|  | public slots: | ||||||
|  | 	void instanceActivated ( QModelIndex ); | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	Ui::MainWindow *ui; | 	Ui::MainWindow *ui; | ||||||
| 	 | 	KCategoryDrawer * drawer; | ||||||
|  | 	KCategorizedView * view; | ||||||
|  | 	InstanceModel * model; | ||||||
|  | 	InstanceProxyModel * proxymodel; | ||||||
| 	InstanceList instList; | 	InstanceList instList; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -33,22 +33,6 @@ | |||||||
|     <property name="bottomMargin"> |     <property name="bottomMargin"> | ||||||
|      <number>0</number> |      <number>0</number> | ||||||
|     </property> |     </property> | ||||||
|     <item> |  | ||||||
|      <widget class="QTreeView" name="instanceView"> |  | ||||||
|       <property name="animated"> |  | ||||||
|        <bool>true</bool> |  | ||||||
|       </property> |  | ||||||
|       <property name="allColumnsShowFocus"> |  | ||||||
|        <bool>true</bool> |  | ||||||
|       </property> |  | ||||||
|       <attribute name="headerVisible"> |  | ||||||
|        <bool>false</bool> |  | ||||||
|       </attribute> |  | ||||||
|       <property name="contextMenuPolicy"> |  | ||||||
|        <enum>Qt::CustomContextMenu</enum> |  | ||||||
|       </property> |  | ||||||
|      </widget> |  | ||||||
|     </item> |  | ||||||
|    </layout> |    </layout> | ||||||
|   </widget> |   </widget> | ||||||
|   <widget class="QToolBar" name="mainToolBar"> |   <widget class="QToolBar" name="mainToolBar"> | ||||||
|   | |||||||
							
								
								
									
										41
									
								
								libgroupview/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								libgroupview/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | project(libGroupView) | ||||||
|  |  | ||||||
|  | set(CMAKE_AUTOMOC ON) | ||||||
|  |  | ||||||
|  | # Find Qt | ||||||
|  | find_package(Qt5Core REQUIRED) | ||||||
|  | find_package(Qt5Gui REQUIRED) | ||||||
|  |  | ||||||
|  | # Include Qt headers. | ||||||
|  | include_directories(${Qt5Base_INCLUDE_DIRS}) | ||||||
|  |  | ||||||
|  | SET(LIBGROUPVIEW_HEADERS | ||||||
|  | include/libgroupview_config.h | ||||||
|  |  | ||||||
|  | # Public headers | ||||||
|  | include/kcategorizedsortfilterproxymodel.h | ||||||
|  | include/kcategorizedview.h | ||||||
|  | include/kcategorydrawer.h | ||||||
|  |  | ||||||
|  | # Private headers | ||||||
|  | src/kcategorizedsortfilterproxymodel_p.h | ||||||
|  | src/kcategorizedview_p.h | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | SET(LIBGROUPVIEW_SOURCES | ||||||
|  | src/kcategorizedsortfilterproxymodel.cpp | ||||||
|  | src/kcategorizedview.cpp | ||||||
|  | src/kcategorydrawer.cpp | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | # Set the include dir path. | ||||||
|  | SET(LIBGROUPVIEW_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include" PARENT_SCOPE) | ||||||
|  |  | ||||||
|  | # Include self. | ||||||
|  | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) | ||||||
|  | include_directories(${CMAKE_BINARY_DIR}/include) | ||||||
|  |  | ||||||
|  | add_definitions(-DLIBGROUPVIEW_LIBRARY) | ||||||
|  |  | ||||||
|  | add_library(libGroupView SHARED ${LIBGROUPVIEW_SOURCES} ${LIBGROUPVIEW_HEADERS}) | ||||||
|  | qt5_use_modules(libGroupView Core Gui) | ||||||
							
								
								
									
										175
									
								
								libgroupview/include/kcategorizedsortfilterproxymodel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								libgroupview/include/kcategorizedsortfilterproxymodel.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,175 @@ | |||||||
|  | /* | ||||||
|  |  * This file is part of the KDE project | ||||||
|  |  * Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org> | ||||||
|  |  * Copyright (C) 2007 John Tapsell <tapsell@kde.org> | ||||||
|  |  * | ||||||
|  |  * This library is free software; you can redistribute it and/or | ||||||
|  |  * modify it under the terms of the GNU Library General Public | ||||||
|  |  * License as published by the Free Software Foundation; either | ||||||
|  |  * version 2 of the License, or (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * This library 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 | ||||||
|  |  * Library General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU Library General Public License | ||||||
|  |  * along with this library; see the file COPYING.LIB.  If not, write to | ||||||
|  |  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||||||
|  |  * Boston, MA 02110-1301, USA. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef KCATEGORIZEDSORTFILTERPROXYMODEL_H | ||||||
|  | #define KCATEGORIZEDSORTFILTERPROXYMODEL_H | ||||||
|  |  | ||||||
|  | #include <QSortFilterProxyModel> | ||||||
|  |  | ||||||
|  | #include <kdeui_export.h> | ||||||
|  |  | ||||||
|  | class QItemSelection; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |   * This class lets you categorize a view. It is meant to be used along with | ||||||
|  |   * KCategorizedView class. | ||||||
|  |   * | ||||||
|  |   * In general terms all you need to do is to reimplement subSortLessThan() and | ||||||
|  |   * compareCategories() methods. In order to make categorization work, you need | ||||||
|  |   * to also call setCategorizedModel() class to enable it, since the categorization | ||||||
|  |   * is disabled by default. | ||||||
|  |   * | ||||||
|  |   * @see KCategorizedView | ||||||
|  |   * | ||||||
|  |   * @author Rafael Fernández López <ereslibre@kde.org> | ||||||
|  |   */ | ||||||
|  | class KDEUI_EXPORT KCategorizedSortFilterProxyModel | ||||||
|  | 	: public QSortFilterProxyModel | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	enum AdditionalRoles | ||||||
|  | 	{ | ||||||
|  | 		// Note: use printf "0x%08X\n" $(($RANDOM*$RANDOM)) | ||||||
|  | 		// to define additional roles. | ||||||
|  | 		CategoryDisplayRole = 0x17CE990A,  ///< This role is used for asking the category to a given index | ||||||
|  |  | ||||||
|  | 		CategorySortRole    = 0x27857E60   ///< This role is used for sorting categories. You can return a | ||||||
|  | 		///< string or a long long value. Strings will be sorted alphabetically | ||||||
|  | 		///< while long long will be sorted by their value. Please note that this | ||||||
|  | 		///< value won't be shown on the view, is only for sorting purposes. What will | ||||||
|  | 		///< be shown as "Category" on the view will be asked with the role | ||||||
|  | 		///< CategoryDisplayRole. | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	KCategorizedSortFilterProxyModel ( QObject *parent = 0 ); | ||||||
|  | 	virtual ~KCategorizedSortFilterProxyModel(); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Overridden from QSortFilterProxyModel. Sorts the source model using | ||||||
|  | 	  * @p column for the given @p order. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void sort ( int column, Qt::SortOrder order = Qt::AscendingOrder ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * @return whether the model is categorized or not. Disabled by default. | ||||||
|  | 	  */ | ||||||
|  | 	bool isCategorizedModel() const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Enables or disables the categorization feature. | ||||||
|  | 	  * | ||||||
|  | 	  * @param categorizedModel whether to enable or disable the categorization feature. | ||||||
|  | 	  */ | ||||||
|  | 	void setCategorizedModel ( bool categorizedModel ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * @return the column being used for sorting. | ||||||
|  | 	  */ | ||||||
|  | 	int sortColumn() const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * @return the sort order being used for sorting. | ||||||
|  | 	  */ | ||||||
|  | 	Qt::SortOrder sortOrder() const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Set if the sorting using CategorySortRole will use a natural comparison | ||||||
|  | 	  * in the case that strings were returned. If enabled, QString::localeAwareCompare | ||||||
|  | 	  * will be used for sorting. | ||||||
|  | 	  * | ||||||
|  | 	  * @param sortCategoriesByNaturalComparison whether to sort using a natural comparison or not. | ||||||
|  | 	  */ | ||||||
|  | 	void setSortCategoriesByNaturalComparison ( bool sortCategoriesByNaturalComparison ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * @return whether it is being used a natural comparison for sorting. Enabled by default. | ||||||
|  | 	  */ | ||||||
|  | 	bool sortCategoriesByNaturalComparison() const; | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  | 	/** | ||||||
|  | 	  * Overridden from QSortFilterProxyModel. If you are subclassing | ||||||
|  | 	  * KCategorizedSortFilterProxyModel, you will probably not need to reimplement this | ||||||
|  | 	  * method. | ||||||
|  | 	  * | ||||||
|  | 	  * It calls compareCategories() to sort by category.  If the both items are in the | ||||||
|  | 	  * same category (i.e. compareCategories returns 0), then subSortLessThan is called. | ||||||
|  | 	  * | ||||||
|  | 	  * @return Returns true if the item @p left is less than the item @p right when sorting. | ||||||
|  | 	  * | ||||||
|  | 	  * @warning You usually won't need to reimplement this method when subclassing | ||||||
|  | 	  *          from KCategorizedSortFilterProxyModel. | ||||||
|  | 	  */ | ||||||
|  | 	virtual bool lessThan ( const QModelIndex &left, const QModelIndex &right ) const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * This method has a similar purpose as lessThan() has on QSortFilterProxyModel. | ||||||
|  | 	  * It is used for sorting items that are in the same category. | ||||||
|  | 	  * | ||||||
|  | 	  * @return Returns true if the item @p left is less than the item @p right when sorting. | ||||||
|  | 	  */ | ||||||
|  | 	virtual bool subSortLessThan ( const QModelIndex &left, const QModelIndex &right ) const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * This method compares the category of the @p left index with the category | ||||||
|  | 	  * of the @p right index. | ||||||
|  | 	  * | ||||||
|  | 	  * Internally and if not reimplemented, this method will ask for @p left and | ||||||
|  | 	  * @p right models for role CategorySortRole. In order to correctly sort | ||||||
|  | 	  * categories, the data() metod of the model should return a qlonglong (or numeric) value, or | ||||||
|  | 	  * a QString object. QString objects will be sorted with QString::localeAwareCompare if | ||||||
|  | 	  * sortCategoriesByNaturalComparison() is true. | ||||||
|  | 	  * | ||||||
|  | 	  * @note Please have present that: | ||||||
|  | 	  *       QString(QChar(QChar::ObjectReplacementCharacter)) > | ||||||
|  | 	  *       QString(QChar(QChar::ReplacementCharacter)) > | ||||||
|  | 	  *       [ all possible strings ] > | ||||||
|  | 	  *       QString(); | ||||||
|  | 	  * | ||||||
|  | 	  *       This means that QString() will be sorted the first one, while | ||||||
|  | 	  *       QString(QChar(QChar::ObjectReplacementCharacter)) and | ||||||
|  | 	  *       QString(QChar(QChar::ReplacementCharacter)) will be sorted in last | ||||||
|  | 	  *       position. | ||||||
|  | 	  * | ||||||
|  | 	  * @warning Please note that data() method of the model should return always | ||||||
|  | 	  *          information of the same type. If you return a QString for an index, | ||||||
|  | 	  *          you should return always QStrings for all indexes for role CategorySortRole | ||||||
|  | 	  *          in order to correctly sort categories. You can't mix by returning | ||||||
|  | 	  *          a QString for one index, and a qlonglong for other. | ||||||
|  | 	  * | ||||||
|  | 	  * @note If you need a more complex layout, you will have to reimplement this | ||||||
|  | 	  *       method. | ||||||
|  | 	  * | ||||||
|  | 	  * @return A negative value if the category of @p left should be placed before the | ||||||
|  | 	  *         category of @p right. 0 if @p left and @p right are on the same category, and | ||||||
|  | 	  *         a positive value if the category of @p left should be placed after the | ||||||
|  | 	  *         category of @p right. | ||||||
|  | 	  */ | ||||||
|  | 	virtual int compareCategories ( const QModelIndex &left, const QModelIndex &right ) const; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	class Private; | ||||||
|  | 	Private *const d; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #endif // KCATEGORIZEDSORTFILTERPROXYMODEL_H | ||||||
							
								
								
									
										322
									
								
								libgroupview/include/kcategorizedview.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										322
									
								
								libgroupview/include/kcategorizedview.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,322 @@ | |||||||
|  | /** | ||||||
|  |   * This file is part of the KDE project | ||||||
|  |   * Copyright (C) 2007, 2009 Rafael Fernández López <ereslibre@kde.org> | ||||||
|  |   * | ||||||
|  |   * This library is free software; you can redistribute it and/or | ||||||
|  |   * modify it under the terms of the GNU Library General Public | ||||||
|  |   * License as published by the Free Software Foundation; either | ||||||
|  |   * version 2 of the License, or (at your option) any later version. | ||||||
|  |   * | ||||||
|  |   * This library 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 | ||||||
|  |   * Library General Public License for more details. | ||||||
|  |   * | ||||||
|  |   * You should have received a copy of the GNU Library General Public License | ||||||
|  |   * along with this library; see the file COPYING.LIB.  If not, write to | ||||||
|  |   * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||||||
|  |   * Boston, MA 02110-1301, USA. | ||||||
|  |   */ | ||||||
|  |  | ||||||
|  | #ifndef KCATEGORIZEDVIEW_H | ||||||
|  | #define KCATEGORIZEDVIEW_H | ||||||
|  |  | ||||||
|  | #include <QListView> | ||||||
|  |  | ||||||
|  | #include <kdeui_export.h> | ||||||
|  |  | ||||||
|  | class KCategoryDrawer; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |   * @short Item view for listing items in a categorized fashion optionally | ||||||
|  |   * | ||||||
|  |   * KCategorizedView basically has the same functionality as QListView, only that it also lets you | ||||||
|  |   * layout items in a way that they are categorized visually. | ||||||
|  |   * | ||||||
|  |   * For it to work you will need to set a KCategorizedSortFilterProxyModel and a KCategoryDrawer | ||||||
|  |   * with methods setModel() and setCategoryDrawer() respectively. Also, the model will need to be | ||||||
|  |   * flagged as categorized with KCategorizedSortFilterProxyModel::setCategorizedModel(true). | ||||||
|  |   * | ||||||
|  |   * The way it works (if categorization enabled): | ||||||
|  |   * | ||||||
|  |   *     - When sorting, it does more things than QListView does. It will ask the model for the | ||||||
|  |   *       special role CategorySortRole (@see KCategorizedSortFilterProxyModel). This can return | ||||||
|  |   *       a QString or an int in order to tell the view the order of categories. In this sense, for | ||||||
|  |   *       instance, if we are sorting by name ascending, "A" would be before than "B". If we are | ||||||
|  |   *       sorting by size ascending, 512 bytes would be before 1024 bytes. This way categories are | ||||||
|  |   *       also sorted. | ||||||
|  |   * | ||||||
|  |   *     - When the view has to paint, it will ask the model with the role CategoryDisplayRole | ||||||
|  |   *       (@see KCategorizedSortFilterProxyModel). It will for instance return "F" for "foo.pdf" if | ||||||
|  |   *       we are sorting by name ascending, or "Small" if a certain item has 100 bytes, for example. | ||||||
|  |   * | ||||||
|  |   * For drawing categories, KCategoryDrawer will be used. You can inherit this class to do your own | ||||||
|  |   * drawing. | ||||||
|  |   * | ||||||
|  |   * @note All examples cited before talk about filesystems and such, but have present that this | ||||||
|  |   *       is a completely generic class, and it can be used for whatever your purpose is. For | ||||||
|  |   *       instance when talking about animals, you can separate them by "Mammal" and "Oviparous". In | ||||||
|  |   *       this very case, for example, the CategorySortRole and the CategoryDisplayRole could be the | ||||||
|  |   *       same ("Mammal" and "Oviparous"). | ||||||
|  |   * | ||||||
|  |   * @note There is a really performance boost if CategorySortRole returns an int instead of a QString. | ||||||
|  |   *       Have present that this role is asked (n * log n) times when sorting and compared. Comparing | ||||||
|  |   *       ints is always faster than comparing strings, whithout mattering how fast the string | ||||||
|  |   *       comparison is. Consider thinking of a way of returning ints instead of QStrings if your | ||||||
|  |   *       model can contain a high number of items. | ||||||
|  |   * | ||||||
|  |   * @warning Note that for really drawing items in blocks you will need some things to be done: | ||||||
|  |   *             - The model set to this view has to be (or inherit if you want to do special stuff | ||||||
|  |   *               in it) KCategorizedSortFilterProxyModel. | ||||||
|  |   *             - This model needs to be set setCategorizedModel to true. | ||||||
|  |   *             - Set a category drawer by calling setCategoryDrawer. | ||||||
|  |   * | ||||||
|  |   * @see KCategorizedSortFilterProxyModel, KCategoryDrawer | ||||||
|  |   * | ||||||
|  |   * @author Rafael Fernández López <ereslibre@kde.org> | ||||||
|  |   */ | ||||||
|  | class KDEUI_EXPORT KCategorizedView | ||||||
|  | 	: public QListView | ||||||
|  | { | ||||||
|  | 	Q_OBJECT | ||||||
|  | 	Q_PROPERTY ( int categorySpacing READ categorySpacing WRITE setCategorySpacing ) | ||||||
|  | 	Q_PROPERTY ( bool alternatingBlockColors READ alternatingBlockColors WRITE setAlternatingBlockColors ) | ||||||
|  | 	Q_PROPERTY ( bool collapsibleBlocks READ collapsibleBlocks WRITE setCollapsibleBlocks ) | ||||||
|  |  | ||||||
|  | public: | ||||||
|  | 	KCategorizedView ( QWidget *parent = 0 ); | ||||||
|  |  | ||||||
|  | 	~KCategorizedView(); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void setModel ( QAbstractItemModel *model ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Calls to setGridSizeOwn(). | ||||||
|  | 	  */ | ||||||
|  | 	void setGridSize ( const QSize &size ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * @warning note that setGridSize is not virtual in the base class (QListView), so if you are | ||||||
|  | 	  *          calling to this method, make sure you have a KCategorizedView pointer around. This | ||||||
|  | 	  *          means that something like: | ||||||
|  | 	  * @code | ||||||
|  | 	  *     QListView *lv = new KCategorizedView(); | ||||||
|  | 	  *     lv->setGridSize(mySize); | ||||||
|  | 	  * @endcode | ||||||
|  | 	  * | ||||||
|  | 	  * will not call to the expected setGridSize method. Instead do something like this: | ||||||
|  | 	  * | ||||||
|  | 	  * @code | ||||||
|  | 	  *     QListView *lv; | ||||||
|  | 	  *     ... | ||||||
|  | 	  *     KCategorizedView *cv = qobject_cast<KCategorizedView*>(lv); | ||||||
|  | 	  *     if (cv) { | ||||||
|  | 	  *         cv->setGridSizeOwn(mySize); | ||||||
|  | 	  *     } else { | ||||||
|  | 	  *         lv->setGridSize(mySize); | ||||||
|  | 	  *     } | ||||||
|  | 	  * @endcode | ||||||
|  | 	  * | ||||||
|  | 	  * @note this method will call to QListView::setGridSize among other operations. | ||||||
|  | 	  * | ||||||
|  | 	  * @since 4.4 | ||||||
|  | 	  */ | ||||||
|  | 	void setGridSizeOwn ( const QSize &size ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual QRect visualRect ( const QModelIndex &index ) const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Returns the current category drawer. | ||||||
|  | 	  */ | ||||||
|  | 	KCategoryDrawer *categoryDrawer() const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * The category drawer that will be used for drawing categories. | ||||||
|  | 	  */ | ||||||
|  | 	void setCategoryDrawer ( KCategoryDrawer *categoryDrawer ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * @return Category spacing. The spacing between categories. | ||||||
|  | 	  * | ||||||
|  | 	  * @since 4.4 | ||||||
|  | 	  */ | ||||||
|  | 	int categorySpacing() const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Stablishes the category spacing. This is the spacing between categories. | ||||||
|  | 	  * | ||||||
|  | 	  * @since 4.4 | ||||||
|  | 	  */ | ||||||
|  | 	void setCategorySpacing ( int categorySpacing ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * @return Whether blocks should be drawn with alternating colors. | ||||||
|  | 	  * | ||||||
|  | 	  * @since 4.4 | ||||||
|  | 	  */ | ||||||
|  | 	bool alternatingBlockColors() const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Sets whether blocks should be drawn with alternating colors. | ||||||
|  | 	  * | ||||||
|  | 	  * @since 4.4 | ||||||
|  | 	  */ | ||||||
|  | 	void setAlternatingBlockColors ( bool enable ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * @return Whether blocks can be collapsed or not. | ||||||
|  | 	  * | ||||||
|  | 	  * @since 4.4 | ||||||
|  | 	  */ | ||||||
|  | 	bool collapsibleBlocks() const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Sets whether blocks can be collapsed or not. | ||||||
|  | 	  * | ||||||
|  | 	  * @since 4.4 | ||||||
|  | 	  */ | ||||||
|  | 	void setCollapsibleBlocks ( bool enable ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * @return Block of indexes that are into @p category. | ||||||
|  | 	  * | ||||||
|  | 	  * @since 4.5 | ||||||
|  | 	  */ | ||||||
|  | 	QModelIndexList block ( const QString &category ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * @return Block of indexes that are represented by @p representative. | ||||||
|  | 	  * | ||||||
|  | 	  * @since 4.5 | ||||||
|  | 	  */ | ||||||
|  | 	QModelIndexList block ( const QModelIndex &representative ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual QModelIndex indexAt ( const QPoint &point ) const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void reset(); | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QWidget. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void paintEvent ( QPaintEvent *event ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QWidget. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void resizeEvent ( QResizeEvent *event ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void setSelection ( const QRect &rect, | ||||||
|  | 	                            QItemSelectionModel::SelectionFlags flags ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QWidget. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void mouseMoveEvent ( QMouseEvent *event ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QWidget. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void mousePressEvent ( QMouseEvent *event ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QWidget. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void mouseReleaseEvent ( QMouseEvent *event ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QWidget. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void leaveEvent ( QEvent *event ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void startDrag ( Qt::DropActions supportedActions ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void dragMoveEvent ( QDragMoveEvent *event ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void dragEnterEvent ( QDragEnterEvent *event ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void dragLeaveEvent ( QDragLeaveEvent *event ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void dropEvent ( QDropEvent *event ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual QModelIndex moveCursor ( CursorAction cursorAction, | ||||||
|  | 	                                 Qt::KeyboardModifiers modifiers ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void rowsAboutToBeRemoved ( const QModelIndex &parent, | ||||||
|  | 	                                    int start, | ||||||
|  | 	                                    int end ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void updateGeometries(); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void currentChanged ( const QModelIndex ¤t, | ||||||
|  | 	                              const QModelIndex &previous ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void dataChanged ( const QModelIndex &topLeft, | ||||||
|  | 	                           const QModelIndex &bottomRight ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Reimplemented from QAbstractItemView. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void rowsInserted ( const QModelIndex &parent, | ||||||
|  | 	                            int start, | ||||||
|  | 	                            int end ); | ||||||
|  |  | ||||||
|  | protected Q_SLOTS: | ||||||
|  | 	/** | ||||||
|  | 	  * @internal | ||||||
|  | 	  * Reposition items as needed. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void slotLayoutChanged(); | ||||||
|  | 	virtual void slotCollapseOrExpandClicked ( QModelIndex ); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	class Private; | ||||||
|  | 	Private *const d; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif // KCATEGORIZEDVIEW_H | ||||||
							
								
								
									
										179
									
								
								libgroupview/include/kcategorydrawer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								libgroupview/include/kcategorydrawer.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,179 @@ | |||||||
|  | /** | ||||||
|  |   * This file is part of the KDE project | ||||||
|  |   * Copyright (C) 2007, 2009 Rafael Fernández López <ereslibre@kde.org> | ||||||
|  |   * | ||||||
|  |   * This library is free software; you can redistribute it and/or | ||||||
|  |   * modify it under the terms of the GNU Library General Public | ||||||
|  |   * License as published by the Free Software Foundation; either | ||||||
|  |   * version 2 of the License, or (at your option) any later version. | ||||||
|  |   * | ||||||
|  |   * This library 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 | ||||||
|  |   * Library General Public License for more details. | ||||||
|  |   * | ||||||
|  |   * You should have received a copy of the GNU Library General Public License | ||||||
|  |   * along with this library; see the file COPYING.LIB.  If not, write to | ||||||
|  |   * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||||||
|  |   * Boston, MA 02110-1301, USA. | ||||||
|  |   */ | ||||||
|  |  | ||||||
|  | #ifndef KCATEGORYDRAWER_H | ||||||
|  | #define KCATEGORYDRAWER_H | ||||||
|  |  | ||||||
|  | #include <libgroupview_config.h> | ||||||
|  |  | ||||||
|  | #include <QtCore/QObject> | ||||||
|  | #include <QtGui/QMouseEvent> | ||||||
|  |  | ||||||
|  | class QPainter; | ||||||
|  | class QModelIndex; | ||||||
|  | class QStyleOption; | ||||||
|  | class KCategorizedView; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |   * @since 4.5 | ||||||
|  |   */ | ||||||
|  | class LIBGROUPVIEW_EXPORT KCategoryDrawer | ||||||
|  | 	: public QObject | ||||||
|  | { | ||||||
|  | 	friend class KCategorizedView; | ||||||
|  | 	Q_OBJECT | ||||||
|  |  | ||||||
|  |  | ||||||
|  | public: | ||||||
|  | 	KCategoryDrawer ( KCategorizedView *view ); | ||||||
|  | 	virtual ~KCategoryDrawer(); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * @return The view this category drawer is associated with. | ||||||
|  | 	  */ | ||||||
|  | 	KCategorizedView *view() const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	     * This method purpose is to draw a category represented by the given | ||||||
|  | 	     * @param index with the given @param sortRole sorting role | ||||||
|  | 	     * | ||||||
|  | 	     * @note This method will be called one time per category, always with the | ||||||
|  | 	     *       first element in that category | ||||||
|  | 	     */ | ||||||
|  | 	virtual void drawCategory ( const QModelIndex &index, | ||||||
|  | 	                            int sortRole, | ||||||
|  | 	                            const QStyleOption &option, | ||||||
|  | 	                            QPainter *painter ) const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * @return The category height for the category representated by index @p index with | ||||||
|  | 	  *         style options @p option. | ||||||
|  | 	  */ | ||||||
|  | 	virtual int categoryHeight ( const QModelIndex &index, const QStyleOption &option ) const; | ||||||
|  |  | ||||||
|  | 	//TODO KDE5: make virtual as leftMargin | ||||||
|  | 	/** | ||||||
|  | 	  * @note 0 by default | ||||||
|  | 	  * | ||||||
|  | 	  * @since 4.4 | ||||||
|  | 	  */ | ||||||
|  | 	int leftMargin() const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * @note call to this method on the KCategoryDrawer constructor to set the left margin | ||||||
|  | 	  * | ||||||
|  | 	  * @since 4.4 | ||||||
|  | 	  */ | ||||||
|  | 	void setLeftMargin ( int leftMargin ); | ||||||
|  |  | ||||||
|  | 	//TODO KDE5: make virtual as rightMargin | ||||||
|  | 	/** | ||||||
|  | 	  * @note 0 by default | ||||||
|  | 	  * | ||||||
|  | 	  * @since 4.4 | ||||||
|  | 	  */ | ||||||
|  | 	int rightMargin() const; | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * @note call to this method on the KCategoryDrawer constructor to set the right margin | ||||||
|  | 	  * | ||||||
|  | 	  * @since 4.4 | ||||||
|  | 	  */ | ||||||
|  | 	void setRightMargin ( int rightMargin ); | ||||||
|  |  | ||||||
|  | 	KCategoryDrawer &operator= ( const KCategoryDrawer &cd ); | ||||||
|  | protected: | ||||||
|  | 	/** | ||||||
|  | 	  * Method called when the mouse button has been pressed. | ||||||
|  | 	  * | ||||||
|  | 	  * @param index The representative index of the block of items. | ||||||
|  | 	  * @param blockRect The rect occupied by the block of items. | ||||||
|  | 	  * @param event The mouse event. | ||||||
|  | 	  * | ||||||
|  | 	  * @warning You explicitly have to determine whether the event has been accepted or not. You | ||||||
|  | 	  *          have to call event->accept() or event->ignore() at all possible case branches in | ||||||
|  | 	  *          your code. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void mouseButtonPressed ( const QModelIndex &index, const QRect &blockRect, QMouseEvent *event ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Method called when the mouse button has been released. | ||||||
|  | 	  * | ||||||
|  | 	  * @param index The representative index of the block of items. | ||||||
|  | 	  * @param blockRect The rect occupied by the block of items. | ||||||
|  | 	  * @param event The mouse event. | ||||||
|  | 	  * | ||||||
|  | 	  * @warning You explicitly have to determine whether the event has been accepted or not. You | ||||||
|  | 	  *          have to call event->accept() or event->ignore() at all possible case branches in | ||||||
|  | 	  *          your code. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void mouseButtonReleased ( const QModelIndex &index, const QRect &blockRect, QMouseEvent *event ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Method called when the mouse has been moved. | ||||||
|  | 	  * | ||||||
|  | 	  * @param index The representative index of the block of items. | ||||||
|  | 	  * @param blockRect The rect occupied by the block of items. | ||||||
|  | 	  * @param event The mouse event. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void mouseMoved ( const QModelIndex &index, const QRect &blockRect, QMouseEvent *event ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Method called when the mouse button has been double clicked. | ||||||
|  | 	  * | ||||||
|  | 	  * @param index The representative index of the block of items. | ||||||
|  | 	  * @param blockRect The rect occupied by the block of items. | ||||||
|  | 	  * @param event The mouse event. | ||||||
|  | 	  * | ||||||
|  | 	  * @warning You explicitly have to determine whether the event has been accepted or not. You | ||||||
|  | 	  *          have to call event->accept() or event->ignore() at all possible case branches in | ||||||
|  | 	  *          your code. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void mouseButtonDoubleClicked ( const QModelIndex &index, const QRect &blockRect, QMouseEvent *event ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Method called when the mouse button has left this block. | ||||||
|  | 	  * | ||||||
|  | 	  * @param index The representative index of the block of items. | ||||||
|  | 	  * @param blockRect The rect occupied by the block of items. | ||||||
|  | 	  */ | ||||||
|  | 	virtual void mouseLeft ( const QModelIndex &index, const QRect &blockRect ); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	class Private; | ||||||
|  | 	Private *const d; | ||||||
|  | Q_SIGNALS: | ||||||
|  | 	/** | ||||||
|  | 	  * This signal becomes emitted when collapse or expand has been clicked. | ||||||
|  | 	  */ | ||||||
|  | 	void collapseOrExpandClicked ( const QModelIndex &index ); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	  * Emit this signal on your subclass implementation to notify that something happened. Usually | ||||||
|  | 	  * this will be triggered when you have received an event, and its position matched some "hot spot". | ||||||
|  | 	  * | ||||||
|  | 	  * You give this action the integer you want, and having connected this signal to your code, | ||||||
|  | 	  * the connected slot can perform the needed changes (view, model, selection model, delegate...) | ||||||
|  | 	  */ | ||||||
|  | 	void actionRequested ( int action, const QModelIndex &index ); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif // KCATEGORYDRAWER_H | ||||||
							
								
								
									
										27
									
								
								libgroupview/include/libgroupview_config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								libgroupview/include/libgroupview_config.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | /* Copyright 2013 MultiMC Contributors | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  * you may not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | //#ifndef LIBINSTANCE_CONFIG_H | ||||||
|  | //#define LIBINSTANCE_CONFIG_H | ||||||
|  |  | ||||||
|  | #include <QtCore/QtGlobal> | ||||||
|  |  | ||||||
|  | #ifdef LIBGROUPVIEW_LIBRARY | ||||||
|  | #  define LIBGROUPVIEW_EXPORT Q_DECL_EXPORT | ||||||
|  | #else | ||||||
|  | #  define LIBGROUPVIEW_EXPORT Q_DECL_IMPORT | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | //#endif // LIBINSTANCE_CONFIG_H | ||||||
							
								
								
									
										168
									
								
								libgroupview/src/kcategorizedsortfilterproxymodel.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								libgroupview/src/kcategorizedsortfilterproxymodel.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,168 @@ | |||||||
|  | /** | ||||||
|  |   * This file is part of the KDE project | ||||||
|  |   * Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org> | ||||||
|  |   * Copyright (C) 2007 John Tapsell <tapsell@kde.org> | ||||||
|  |   * | ||||||
|  |   * This library is free software; you can redistribute it and/or | ||||||
|  |   * modify it under the terms of the GNU Library General Public | ||||||
|  |   * License as published by the Free Software Foundation; either | ||||||
|  |   * version 2 of the License, or (at your option) any later version. | ||||||
|  |   * | ||||||
|  |   * This library 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 | ||||||
|  |   * Library General Public License for more details. | ||||||
|  |   * | ||||||
|  |   * You should have received a copy of the GNU Library General Public License | ||||||
|  |   * along with this library; see the file COPYING.LIB.  If not, write to | ||||||
|  |   * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||||||
|  |   * Boston, MA 02110-1301, USA. | ||||||
|  |   */ | ||||||
|  |  | ||||||
|  | #include "kcategorizedsortfilterproxymodel.h" | ||||||
|  | #include "kcategorizedsortfilterproxymodel_p.h" | ||||||
|  |  | ||||||
|  | #include <limits.h> | ||||||
|  |  | ||||||
|  | #include <QItemSelection> | ||||||
|  | #include <QStringList> | ||||||
|  | #include <QSize> | ||||||
|  |  | ||||||
|  | KCategorizedSortFilterProxyModel::KCategorizedSortFilterProxyModel ( QObject *parent ) | ||||||
|  | 	: QSortFilterProxyModel ( parent ) | ||||||
|  | 	, d ( new Private() ) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | KCategorizedSortFilterProxyModel::~KCategorizedSortFilterProxyModel() | ||||||
|  | { | ||||||
|  | 	delete d; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void KCategorizedSortFilterProxyModel::sort ( int column, Qt::SortOrder order ) | ||||||
|  | { | ||||||
|  | 	d->sortColumn = column; | ||||||
|  | 	d->sortOrder = order; | ||||||
|  |  | ||||||
|  | 	QSortFilterProxyModel::sort ( column, order ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool KCategorizedSortFilterProxyModel::isCategorizedModel() const | ||||||
|  | { | ||||||
|  | 	return d->categorizedModel; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void KCategorizedSortFilterProxyModel::setCategorizedModel ( bool categorizedModel ) | ||||||
|  | { | ||||||
|  | 	if ( categorizedModel == d->categorizedModel ) | ||||||
|  | 	{ | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	d->categorizedModel = categorizedModel; | ||||||
|  |  | ||||||
|  | 	invalidate(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int KCategorizedSortFilterProxyModel::sortColumn() const | ||||||
|  | { | ||||||
|  | 	return d->sortColumn; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Qt::SortOrder KCategorizedSortFilterProxyModel::sortOrder() const | ||||||
|  | { | ||||||
|  | 	return d->sortOrder; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void KCategorizedSortFilterProxyModel::setSortCategoriesByNaturalComparison ( bool sortCategoriesByNaturalComparison ) | ||||||
|  | { | ||||||
|  | 	if ( sortCategoriesByNaturalComparison == d->sortCategoriesByNaturalComparison ) | ||||||
|  | 	{ | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	d->sortCategoriesByNaturalComparison = sortCategoriesByNaturalComparison; | ||||||
|  |  | ||||||
|  | 	invalidate(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool KCategorizedSortFilterProxyModel::sortCategoriesByNaturalComparison() const | ||||||
|  | { | ||||||
|  | 	return d->sortCategoriesByNaturalComparison; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool KCategorizedSortFilterProxyModel::lessThan ( const QModelIndex &left, const QModelIndex &right ) const | ||||||
|  | { | ||||||
|  | 	if ( d->categorizedModel ) | ||||||
|  | 	{ | ||||||
|  | 		int compare = compareCategories ( left, right ); | ||||||
|  |  | ||||||
|  | 		if ( compare > 0 ) // left is greater than right | ||||||
|  | 		{ | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 		else if ( compare < 0 ) // left is less than right | ||||||
|  | 		{ | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return subSortLessThan ( left, right ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool KCategorizedSortFilterProxyModel::subSortLessThan ( const QModelIndex &left, const QModelIndex &right ) const | ||||||
|  | { | ||||||
|  | 	return QSortFilterProxyModel::lessThan ( left, right ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int KCategorizedSortFilterProxyModel::compareCategories ( const QModelIndex &left, const QModelIndex &right ) const | ||||||
|  | { | ||||||
|  | 	QVariant l = ( left.model() ? left.model()->data ( left, CategorySortRole ) : QVariant() ); | ||||||
|  | 	QVariant r = ( right.model() ? right.model()->data ( right, CategorySortRole ) : QVariant() ); | ||||||
|  |  | ||||||
|  | 	Q_ASSERT ( l.isValid() ); | ||||||
|  | 	Q_ASSERT ( r.isValid() ); | ||||||
|  | 	Q_ASSERT ( l.type() == r.type() ); | ||||||
|  |  | ||||||
|  | 	if ( l.type() == QVariant::String ) | ||||||
|  | 	{ | ||||||
|  | 		QString lstr = l.toString(); | ||||||
|  | 		QString rstr = r.toString(); | ||||||
|  |  | ||||||
|  | 		/* | ||||||
|  | 		if ( d->sortCategoriesByNaturalComparison ) | ||||||
|  | 		{ | ||||||
|  | 			return KStringHandler::naturalCompare ( lstr, rstr ); | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			*/ | ||||||
|  | 			if ( lstr < rstr ) | ||||||
|  | 			{ | ||||||
|  | 				return -1; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if ( lstr > rstr ) | ||||||
|  | 			{ | ||||||
|  | 				return 1; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return 0; | ||||||
|  | 		//} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	qlonglong lint = l.toLongLong(); | ||||||
|  | 	qlonglong rint = r.toLongLong(); | ||||||
|  |  | ||||||
|  | 	if ( lint < rint ) | ||||||
|  | 	{ | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if ( lint > rint ) | ||||||
|  | 	{ | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								libgroupview/src/kcategorizedsortfilterproxymodel_p.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								libgroupview/src/kcategorizedsortfilterproxymodel_p.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | /** | ||||||
|  |   * This file is part of the KDE project | ||||||
|  |   * Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org> | ||||||
|  |   * Copyright (C) 2007 John Tapsell <tapsell@kde.org> | ||||||
|  |   * | ||||||
|  |   * This library is free software; you can redistribute it and/or | ||||||
|  |   * modify it under the terms of the GNU Library General Public | ||||||
|  |   * License as published by the Free Software Foundation; either | ||||||
|  |   * version 2 of the License, or (at your option) any later version. | ||||||
|  |   * | ||||||
|  |   * This library 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 | ||||||
|  |   * Library General Public License for more details. | ||||||
|  |   * | ||||||
|  |   * You should have received a copy of the GNU Library General Public License | ||||||
|  |   * along with this library; see the file COPYING.LIB.  If not, write to | ||||||
|  |   * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||||||
|  |   * Boston, MA 02110-1301, USA. | ||||||
|  |   */ | ||||||
|  |  | ||||||
|  | #ifndef KCATEGORIZEDSORTFILTERPROXYMODEL_P_H | ||||||
|  | #define KCATEGORIZEDSORTFILTERPROXYMODEL_P_H | ||||||
|  |  | ||||||
|  | class KCategorizedSortFilterProxyModel; | ||||||
|  |  | ||||||
|  | class KCategorizedSortFilterProxyModel::Private | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	Private() | ||||||
|  | 		: sortColumn ( 0 ) | ||||||
|  | 		, sortOrder ( Qt::AscendingOrder ) | ||||||
|  | 		, categorizedModel ( false ) | ||||||
|  | 		, sortCategoriesByNaturalComparison ( true ) | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	~Private() | ||||||
|  | 	{ | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	int sortColumn; | ||||||
|  | 	Qt::SortOrder sortOrder; | ||||||
|  | 	bool categorizedModel; | ||||||
|  | 	bool sortCategoriesByNaturalComparison; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif | ||||||
							
								
								
									
										1696
									
								
								libgroupview/src/kcategorizedview.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1696
									
								
								libgroupview/src/kcategorizedview.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										157
									
								
								libgroupview/src/kcategorizedview_p.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								libgroupview/src/kcategorizedview_p.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,157 @@ | |||||||
|  | /** | ||||||
|  |   * This file is part of the KDE project | ||||||
|  |   * Copyright (C) 2007, 2009 Rafael Fernández López <ereslibre@kde.org> | ||||||
|  |   * | ||||||
|  |   * This library is free software; you can redistribute it and/or | ||||||
|  |   * modify it under the terms of the GNU Library General Public | ||||||
|  |   * License as published by the Free Software Foundation; either | ||||||
|  |   * version 2 of the License, or (at your option) any later version. | ||||||
|  |   * | ||||||
|  |   * This library 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 | ||||||
|  |   * Library General Public License for more details. | ||||||
|  |   * | ||||||
|  |   * You should have received a copy of the GNU Library General Public License | ||||||
|  |   * along with this library; see the file COPYING.LIB.  If not, write to | ||||||
|  |   * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||||||
|  |   * Boston, MA 02110-1301, USA. | ||||||
|  |   */ | ||||||
|  |  | ||||||
|  | #ifndef KCATEGORIZEDVIEW_P_H | ||||||
|  | #define KCATEGORIZEDVIEW_P_H | ||||||
|  |  | ||||||
|  | class KCategorizedSortFilterProxyModel; | ||||||
|  | class KCategoryDrawer; | ||||||
|  | class KCategoryDrawerV2; | ||||||
|  | class KCategoryDrawerV3; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |   * @internal | ||||||
|  |   */ | ||||||
|  | class KCategorizedView::Private | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     struct Block; | ||||||
|  |     struct Item; | ||||||
|  |  | ||||||
|  |     Private(KCategorizedView *q); | ||||||
|  |     ~Private(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * @return whether this view has all required elements to be categorized. | ||||||
|  |       */ | ||||||
|  |     bool isCategorized() const; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * @return the block rect for the representative @p representative. | ||||||
|  |       */ | ||||||
|  |     QStyleOptionViewItemV4 blockRect(const QModelIndex &representative); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * Returns the first and last element that intersects with rect. | ||||||
|  |       * | ||||||
|  |       * @note see that here we cannot take out items between first and last (as we could | ||||||
|  |       *       do with the rubberband). | ||||||
|  |       * | ||||||
|  |       * Complexity: O(log(n)) where n is model()->rowCount(). | ||||||
|  |       */ | ||||||
|  |     QPair<QModelIndex, QModelIndex> intersectingIndexesWithRect(const QRect &rect) const; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * Returns the position of the block of @p category. | ||||||
|  |       * | ||||||
|  |       * Complexity: O(n) where n is the number of different categories when the block has been | ||||||
|  |       *             marked as in quarantine. O(1) the rest of the times (the vast majority). | ||||||
|  |       */ | ||||||
|  |     QPoint blockPosition(const QString &category); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * Returns the height of the block determined by @p category. | ||||||
|  |       */ | ||||||
|  |     int blockHeight(const QString &category); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * Returns the actual viewport width. | ||||||
|  |       */ | ||||||
|  |     int viewportWidth() const; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * Marks all elements as in quarantine. | ||||||
|  |       * | ||||||
|  |       * Complexity: O(n) where n is model()->rowCount(). | ||||||
|  |       * | ||||||
|  |       * @warning this is an expensive operation | ||||||
|  |       */ | ||||||
|  |     void regenerateAllElements(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * Update internal information, and keep sync with the real information that the model contains. | ||||||
|  |       */ | ||||||
|  |     void rowsInserted(const QModelIndex &parent, int start, int end); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * Returns @p rect in viewport terms, taking in count horizontal and vertical offsets. | ||||||
|  |       */ | ||||||
|  |     QRect mapToViewport(const QRect &rect) const; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * Returns @p rect in absolute terms, converted from viewport position. | ||||||
|  |       */ | ||||||
|  |     QRect mapFromViewport(const QRect &rect) const; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * Returns the height of the highest element in last row. This is only applicable if there is | ||||||
|  |       * no grid set and uniformItemSizes is false. | ||||||
|  |       * | ||||||
|  |       * @param block in which block are we searching. Necessary to stop the search if we hit the | ||||||
|  |       *              first item in this block. | ||||||
|  |       */ | ||||||
|  |     int highestElementInLastRow(const Block &block) const; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * Returns whether the view has a valid grid size. | ||||||
|  |       */ | ||||||
|  |     bool hasGrid() const; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * Returns the category for the given index. | ||||||
|  |       */ | ||||||
|  |     QString categoryForIndex(const QModelIndex &index) const; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * Updates the visual rect for item when flow is LeftToRight. | ||||||
|  |       */ | ||||||
|  |     void leftToRightVisualRect(const QModelIndex &index, Item &item, | ||||||
|  |                                const Block &block, const QPoint &blockPos) const; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * Updates the visual rect for item when flow is TopToBottom. | ||||||
|  |       * @note we only support viewMode == ListMode in this case. | ||||||
|  |       */ | ||||||
|  |     void topToBottomVisualRect(const QModelIndex &index, Item &item, | ||||||
|  |                                const Block &block, const QPoint &blockPos) const; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |       * Called when expand or collapse has been clicked on the category drawer. | ||||||
|  |       */ | ||||||
|  |     void _k_slotCollapseOrExpandClicked(QModelIndex); | ||||||
|  |  | ||||||
|  |     KCategorizedView *q; | ||||||
|  |     KCategorizedSortFilterProxyModel *proxyModel; | ||||||
|  |     KCategoryDrawer *categoryDrawer; | ||||||
|  |     int categorySpacing; | ||||||
|  |     bool alternatingBlockColors; | ||||||
|  |     bool collapsibleBlocks; | ||||||
|  |  | ||||||
|  |     Block *hoveredBlock; | ||||||
|  |     QString hoveredCategory; | ||||||
|  |     QModelIndex hoveredIndex; | ||||||
|  |  | ||||||
|  |     QPoint pressedPosition; | ||||||
|  |     QRect rubberBandRect; | ||||||
|  |  | ||||||
|  |     QHash<QString, Block> blocks; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif // KCATEGORIZEDVIEW_P_H | ||||||
							
								
								
									
										231
									
								
								libgroupview/src/kcategorydrawer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								libgroupview/src/kcategorydrawer.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,231 @@ | |||||||
|  | /** | ||||||
|  |   * This file is part of the KDE project | ||||||
|  |   * Copyright (C) 2007, 2009 Rafael Fernández López <ereslibre@kde.org> | ||||||
|  |   * | ||||||
|  |   * This library is free software; you can redistribute it and/or | ||||||
|  |   * modify it under the terms of the GNU Library General Public | ||||||
|  |   * License as published by the Free Software Foundation; either | ||||||
|  |   * version 2 of the License, or (at your option) any later version. | ||||||
|  |   * | ||||||
|  |   * This library 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 | ||||||
|  |   * Library General Public License for more details. | ||||||
|  |   * | ||||||
|  |   * You should have received a copy of the GNU Library General Public License | ||||||
|  |   * along with this library; see the file COPYING.LIB.  If not, write to | ||||||
|  |   * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||||||
|  |   * Boston, MA 02110-1301, USA. | ||||||
|  |   */ | ||||||
|  |  | ||||||
|  | #include "kcategorydrawer.h" | ||||||
|  |  | ||||||
|  | #include <QPainter> | ||||||
|  | #include <QStyleOption> | ||||||
|  | #include <QApplication> | ||||||
|  |  | ||||||
|  | #include <kcategorizedview.h> | ||||||
|  | #include <kcategorizedsortfilterproxymodel.h> | ||||||
|  |  | ||||||
|  | #define HORIZONTAL_HINT 3 | ||||||
|  |  | ||||||
|  | class KCategoryDrawer::Private | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 	Private(KCategorizedView *view) | ||||||
|  | 		: view(view) | ||||||
|  | 		, leftMargin(0) | ||||||
|  | 		, rightMargin(0) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ~Private() | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |     int leftMargin; | ||||||
|  |     int rightMargin; | ||||||
|  |     KCategorizedView *view; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | KCategoryDrawer::KCategoryDrawer(KCategorizedView *view) | ||||||
|  |     : QObject(view) | ||||||
|  |     , d(new Private(view)) | ||||||
|  | { | ||||||
|  | 	setLeftMargin(2); | ||||||
|  | 	setRightMargin(2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | KCategoryDrawer::~KCategoryDrawer() | ||||||
|  | { | ||||||
|  |     delete d; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void KCategoryDrawer::drawCategory(const QModelIndex &index, | ||||||
|  |                                    int /*sortRole*/, | ||||||
|  |                                    const QStyleOption &option, | ||||||
|  |                                    QPainter *painter) const | ||||||
|  | { | ||||||
|  |     painter->setRenderHint(QPainter::Antialiasing); | ||||||
|  |  | ||||||
|  |     const QString category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString(); | ||||||
|  |     const QRect optRect = option.rect; | ||||||
|  |     QFont font(QApplication::font()); | ||||||
|  |     font.setBold(true); | ||||||
|  |     const QFontMetrics fontMetrics = QFontMetrics(font); | ||||||
|  |  | ||||||
|  |     QColor outlineColor = option.palette.text().color(); | ||||||
|  |     outlineColor.setAlphaF(0.35); | ||||||
|  |  | ||||||
|  |     //BEGIN: top left corner | ||||||
|  |     { | ||||||
|  |         painter->save(); | ||||||
|  |         painter->setPen(outlineColor); | ||||||
|  |         const QPointF topLeft(optRect.topLeft()); | ||||||
|  |         QRectF arc(topLeft, QSizeF(4, 4)); | ||||||
|  |         arc.translate(0.5, 0.5); | ||||||
|  |         painter->drawArc(arc, 1440, 1440); | ||||||
|  |         painter->restore(); | ||||||
|  |     } | ||||||
|  |     //END: top left corner | ||||||
|  |  | ||||||
|  |     //BEGIN: left vertical line | ||||||
|  |     { | ||||||
|  |         QPoint start(optRect.topLeft()); | ||||||
|  |         start.ry() += 3; | ||||||
|  |         QPoint verticalGradBottom(optRect.topLeft()); | ||||||
|  |         verticalGradBottom.ry() += fontMetrics.height() + 5; | ||||||
|  |         QLinearGradient gradient(start, verticalGradBottom); | ||||||
|  |         gradient.setColorAt(0, outlineColor); | ||||||
|  |         gradient.setColorAt(1, Qt::transparent); | ||||||
|  |         painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient); | ||||||
|  |     } | ||||||
|  |     //END: left vertical line | ||||||
|  |  | ||||||
|  |     //BEGIN: horizontal line | ||||||
|  |     { | ||||||
|  |         QPoint start(optRect.topLeft()); | ||||||
|  |         start.rx() += 3; | ||||||
|  |         QPoint horizontalGradTop(optRect.topLeft()); | ||||||
|  |         horizontalGradTop.rx() += optRect.width() - 6; | ||||||
|  |         painter->fillRect(QRect(start, QSize(optRect.width() - 6, 1)), outlineColor); | ||||||
|  |     } | ||||||
|  |     //END: horizontal line | ||||||
|  |  | ||||||
|  |     //BEGIN: top right corner | ||||||
|  |     { | ||||||
|  |         painter->save(); | ||||||
|  |         painter->setPen(outlineColor); | ||||||
|  |         QPointF topRight(optRect.topRight()); | ||||||
|  |         topRight.rx() -= 4; | ||||||
|  |         QRectF arc(topRight, QSizeF(4, 4)); | ||||||
|  |         arc.translate(0.5, 0.5); | ||||||
|  |         painter->drawArc(arc, 0, 1440); | ||||||
|  |         painter->restore(); | ||||||
|  |     } | ||||||
|  |     //END: top right corner | ||||||
|  |  | ||||||
|  |     //BEGIN: right vertical line | ||||||
|  |     { | ||||||
|  |         QPoint start(optRect.topRight()); | ||||||
|  |         start.ry() += 3; | ||||||
|  |         QPoint verticalGradBottom(optRect.topRight()); | ||||||
|  |         verticalGradBottom.ry() += fontMetrics.height() + 5; | ||||||
|  |         QLinearGradient gradient(start, verticalGradBottom); | ||||||
|  |         gradient.setColorAt(0, outlineColor); | ||||||
|  |         gradient.setColorAt(1, Qt::transparent); | ||||||
|  |         painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient); | ||||||
|  |     } | ||||||
|  |     //END: right vertical line | ||||||
|  |  | ||||||
|  |     //BEGIN: text | ||||||
|  |     { | ||||||
|  |         QRect textRect(option.rect); | ||||||
|  |         textRect.setTop(textRect.top() + 7); | ||||||
|  |         textRect.setLeft(textRect.left() + 7); | ||||||
|  |         textRect.setHeight(fontMetrics.height()); | ||||||
|  |         textRect.setRight(textRect.right() - 7); | ||||||
|  |  | ||||||
|  |         painter->save(); | ||||||
|  |         painter->setFont(font); | ||||||
|  |         QColor penColor(option.palette.text().color()); | ||||||
|  |         penColor.setAlphaF(0.6); | ||||||
|  |         painter->setPen(penColor); | ||||||
|  |         painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, category); | ||||||
|  |         painter->restore(); | ||||||
|  |     } | ||||||
|  |     //END: text | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int KCategoryDrawer::categoryHeight(const QModelIndex &index, const QStyleOption &option) const | ||||||
|  | { | ||||||
|  |     Q_UNUSED(index); | ||||||
|  |     Q_UNUSED(option) | ||||||
|  |  | ||||||
|  |     QFont font(QApplication::font()); | ||||||
|  |     font.setBold(true); | ||||||
|  |     QFontMetrics fontMetrics(font); | ||||||
|  |  | ||||||
|  |     const int height = fontMetrics.height() + 1 /* 1 pixel-width gradient */ | ||||||
|  |                                             + 11 /* top and bottom separation */; | ||||||
|  |     return height; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int KCategoryDrawer::leftMargin() const | ||||||
|  | { | ||||||
|  |     return d->leftMargin; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void KCategoryDrawer::setLeftMargin(int leftMargin) | ||||||
|  | { | ||||||
|  |     d->leftMargin = leftMargin; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int KCategoryDrawer::rightMargin() const | ||||||
|  | { | ||||||
|  |     return d->rightMargin; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void KCategoryDrawer::setRightMargin(int rightMargin) | ||||||
|  | { | ||||||
|  |     d->rightMargin = rightMargin; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | KCategoryDrawer &KCategoryDrawer::operator=(const KCategoryDrawer &cd) | ||||||
|  | { | ||||||
|  |     d->leftMargin = cd.d->leftMargin; | ||||||
|  |     d->rightMargin = cd.d->rightMargin; | ||||||
|  | 	d->view = cd.d->view; | ||||||
|  |     return *this; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | KCategorizedView *KCategoryDrawer::view() const | ||||||
|  | { | ||||||
|  |     return d->view; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void KCategoryDrawer::mouseButtonPressed(const QModelIndex&, const QRect&, QMouseEvent *event) | ||||||
|  | { | ||||||
|  |     event->ignore(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void KCategoryDrawer::mouseButtonReleased(const QModelIndex&, const QRect&, QMouseEvent *event) | ||||||
|  | { | ||||||
|  |     event->ignore(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void KCategoryDrawer::mouseMoved(const QModelIndex&, const QRect&, QMouseEvent *event) | ||||||
|  | { | ||||||
|  |     event->ignore(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void KCategoryDrawer::mouseButtonDoubleClicked(const QModelIndex&, const QRect&, QMouseEvent *event) | ||||||
|  | { | ||||||
|  |     event->ignore(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void KCategoryDrawer::mouseLeft(const QModelIndex&, const QRect&) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #include "kcategorydrawer.moc" | ||||||
| @@ -18,11 +18,11 @@ | |||||||
|  |  | ||||||
| #include <QObject> | #include <QObject> | ||||||
|  |  | ||||||
| #include <basicsettingsobject.h> | #include <inisettingsobject.h> | ||||||
|  |  | ||||||
| #include "libmmc_config.h" | #include "libmmc_config.h" | ||||||
|  |  | ||||||
| class LIBMULTIMC_EXPORT AppSettings : public BasicSettingsObject | class LIBMULTIMC_EXPORT AppSettings : public INISettingsObject | ||||||
| { | { | ||||||
| 	Q_OBJECT | 	Q_OBJECT | ||||||
| public: | public: | ||||||
|   | |||||||
| @@ -30,20 +30,20 @@ class LIBMULTIMC_EXPORT LoginTask : public Task | |||||||
| { | { | ||||||
| 	Q_OBJECT | 	Q_OBJECT | ||||||
| public: | public: | ||||||
| 	explicit LoginTask(const UserInfo& uInfo, QObject *parent = 0); | 	explicit LoginTask(const UserInfo& uInfo, QString inst, QObject *parent = 0); | ||||||
| 	 | 	 | ||||||
| public slots: | public slots: | ||||||
| 	void processNetReply(QNetworkReply* reply); | 	void processNetReply(QNetworkReply* reply); | ||||||
| 	 | 	 | ||||||
| signals: | signals: | ||||||
| 	void loginComplete(LoginResponse loginResponse); | 	void loginComplete(QString inst, LoginResponse loginResponse); | ||||||
| 	void loginFailed(const QString& errorMsg); | 	void loginFailed(QString inst, const QString& errorMsg); | ||||||
| 	 | 	 | ||||||
| protected: | protected: | ||||||
| 	void executeTask(); | 	void executeTask(); | ||||||
| 	 | 	 | ||||||
| 	QNetworkReply* netReply; | 	QNetworkReply* netReply; | ||||||
| 	 | 	QString inst; | ||||||
| 	UserInfo uInfo; | 	UserInfo uInfo; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,10 +18,11 @@ | |||||||
| #include <setting.h> | #include <setting.h> | ||||||
|  |  | ||||||
| #include <QPoint> | #include <QPoint> | ||||||
|  | #include <QApplication> | ||||||
| //#include <QColor> | //#include <QColor> | ||||||
|  |  | ||||||
| AppSettings::AppSettings(QObject *parent) : | AppSettings::AppSettings(QObject *parent) : | ||||||
| 	BasicSettingsObject(parent) | 	INISettingsObject(QApplication::applicationDirPath() + "/multimc.cfg",parent) | ||||||
| { | { | ||||||
| 	// Updates | 	// Updates | ||||||
| 	registerSetting(new Setting("UseDevBuilds", false)); | 	registerSetting(new Setting("UseDevBuilds", false)); | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| InstanceList::InstanceList(const QString &instDir, QObject *parent) : | InstanceList::InstanceList(const QString &instDir, QObject *parent) : | ||||||
| 	QObject(parent), m_instDir(instDir) | 	QObject(parent), m_instDir("instances") | ||||||
| { | { | ||||||
| 	 | 	 | ||||||
| } | } | ||||||
|   | |||||||
| @@ -24,8 +24,8 @@ | |||||||
| #include <QUrl> | #include <QUrl> | ||||||
| #include <QUrlQuery> | #include <QUrlQuery> | ||||||
|  |  | ||||||
| LoginTask::LoginTask(const UserInfo &uInfo, QObject *parent) : | LoginTask::LoginTask( const UserInfo& uInfo, QString inst, QObject* parent ) : | ||||||
| 	Task(parent), uInfo(uInfo) | 	Task(parent), uInfo(uInfo), inst(inst) | ||||||
| { | { | ||||||
| 	 | 	 | ||||||
| } | } | ||||||
| @@ -78,42 +78,42 @@ void LoginTask::processNetReply(QNetworkReply *reply) | |||||||
| 					QString sessionID = strings[3]; | 					QString sessionID = strings[3]; | ||||||
| 					 | 					 | ||||||
| 					LoginResponse response(username, sessionID, latestVersion); | 					LoginResponse response(username, sessionID, latestVersion); | ||||||
| 					emit loginComplete(response); | 					emit loginComplete(inst, response); | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| 				{ | 				{ | ||||||
| 					emit loginFailed("Failed to parse Minecraft version string."); | 					emit loginFailed(inst, "Failed to parse Minecraft version string."); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				if (responseStr.toLower() == "bad login") | 				if (responseStr.toLower() == "bad login") | ||||||
| 					emit loginFailed("Invalid username or password."); | 					emit loginFailed(inst, "Invalid username or password."); | ||||||
| 				else if (responseStr.toLower() == "old version") | 				else if (responseStr.toLower() == "old version") | ||||||
| 					emit loginFailed("Launcher outdated, please update."); | 					emit loginFailed(inst, "Launcher outdated, please update."); | ||||||
| 				else | 				else | ||||||
| 					emit loginFailed("Login failed: " + responseStr); | 					emit loginFailed(inst, "Login failed: " + responseStr); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else if (responseCode == 503) | 		else if (responseCode == 503) | ||||||
| 		{ | 		{ | ||||||
| 			emit loginFailed("The login servers are currently unavailable. " | 			emit loginFailed(inst, "The login servers are currently unavailable. " | ||||||
| 							 "Check http://help.mojang.com/ for more info."); | 							 "Check http://help.mojang.com/ for more info."); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			emit loginFailed(QString("Login failed: Unknown HTTP error %1 occurred."). | 			emit loginFailed(inst, QString("Login failed: Unknown HTTP error %1 occurred."). | ||||||
| 							 arg(QString::number(responseCode))); | 							 arg(QString::number(responseCode))); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 		 | 		 | ||||||
| 	case QNetworkReply::OperationCanceledError: | 	case QNetworkReply::OperationCanceledError: | ||||||
| 		emit loginFailed("Login canceled."); | 		emit loginFailed(inst, "Login canceled."); | ||||||
| 		break; | 		break; | ||||||
| 		 | 		 | ||||||
| 	default: | 	default: | ||||||
| 		emit loginFailed("Login failed: " + reply->errorString()); | 		emit loginFailed(inst, "Login failed: " + reply->errorString()); | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								main.cpp
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								main.cpp
									
									
									
									
									
								
							| @@ -81,7 +81,7 @@ private slots: | |||||||
| 		QApplication::instance()->quit(); | 		QApplication::instance()->quit(); | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	void onLoginComplete(LoginResponse response) | 	void onLoginComplete(QString instId, LoginResponse response) | ||||||
| 	{ | 	{ | ||||||
| 		// TODO: console | 		// TODO: console | ||||||
| 		console = new ConsoleWindow(); | 		console = new ConsoleWindow(); | ||||||
| @@ -92,7 +92,7 @@ private slots: | |||||||
| 		proc->launch(); | 		proc->launch(); | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	void doLogin(const QString &errorMsg) | 	void doLogin(QString instId, const QString &errorMsg) | ||||||
| 	{ | 	{ | ||||||
| 		LoginDialog* loginDlg = new LoginDialog(nullptr, errorMsg); | 		LoginDialog* loginDlg = new LoginDialog(nullptr, errorMsg); | ||||||
| 		if (loginDlg->exec()) | 		if (loginDlg->exec()) | ||||||
| @@ -100,11 +100,11 @@ private slots: | |||||||
| 			UserInfo uInfo(loginDlg->getUsername(), loginDlg->getPassword()); | 			UserInfo uInfo(loginDlg->getUsername(), loginDlg->getPassword()); | ||||||
| 			 | 			 | ||||||
| 			TaskDialog* tDialog = new TaskDialog(nullptr); | 			TaskDialog* tDialog = new TaskDialog(nullptr); | ||||||
| 			LoginTask* loginTask = new LoginTask(uInfo, tDialog); | 			LoginTask* loginTask = new LoginTask(uInfo, instance.data()->id(), tDialog); | ||||||
| 			connect(loginTask, SIGNAL(loginComplete(LoginResponse)), | 			connect(loginTask, SIGNAL(loginComplete(QString, LoginResponse)), | ||||||
| 					SLOT(onLoginComplete(LoginResponse)), Qt::QueuedConnection); | 					SLOT(onLoginComplete(QString, LoginResponse)), Qt::QueuedConnection); | ||||||
| 			connect(loginTask, SIGNAL(loginFailed(QString)), | 			connect(loginTask, SIGNAL(loginFailed(QString, QString)), | ||||||
| 					SLOT(doLogin(QString)), Qt::QueuedConnection); | 					SLOT(doLogin(QString, QString)), Qt::QueuedConnection); | ||||||
| 			tDialog->exec(loginTask); | 			tDialog->exec(loginTask); | ||||||
| 		} | 		} | ||||||
| 		//onLoginComplete(LoginResponse("Offline","Offline", 1)); | 		//onLoginComplete(LoginResponse("Offline","Offline", 1)); | ||||||
| @@ -125,7 +125,7 @@ public: | |||||||
| 		} | 		} | ||||||
| 		 | 		 | ||||||
| 		std::cout << "Logging in..." << std::endl; | 		std::cout << "Logging in..." << std::endl; | ||||||
| 		doLogin(""); | 		doLogin(instance->id(),""); | ||||||
| 		 | 		 | ||||||
| 		return QApplication::instance()->exec(); | 		return QApplication::instance()->exec(); | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Petr Mrázek
					Petr Mrázek