plugin system: first demo version

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@970 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
beardog_uk 2009-02-01 16:37:07 +00:00
parent 02f08644ac
commit 79e45e7d37
21 changed files with 2066 additions and 0 deletions

View File

@ -0,0 +1,158 @@
#include <QGroupBox>
#include <QFrame>
#include <QVBoxLayout>
#include <QTabWidget>
#include <QLabel>
#include <QSizePolicy>
#include <QtPlugin>
#include <QPluginLoader>
#include <QDir>
#include <QDebug>
#include <QUiLoader>
#include <QtScript>
#include <QFile>
#include <QMessageBox>
#include "PluginsPage.h"
#include "rshare.h"
#include "plugins/PluginInterface.h"
//==============================================================================
PluginsPage::PluginsPage(QWidget *parent )
:MainPage(parent)
{
pluginPageLayout = new QVBoxLayout(this);
pluginPanel = new QGroupBox(this) ;
pluginPanel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding) ;
pluginPanel->setTitle("RetroShare plugins");
pluginPageLayout->addWidget(pluginPanel);
pluginPanelLayout = new QVBoxLayout(pluginPanel);
pluginTabs = new QTabWidget(pluginPanel);
pluginPanelLayout->addWidget(pluginTabs);
QLabel* lbl1 = new QLabel();
lbl1->setText("If you see only this tab, it's a bug :( If you see this tub and calculator, it's a bug too");
pluginTabs->addTab(lbl1, "LLL");//Rshare::dataDirectory());
//"L #1");
//QLabel* lbl2 = new QLabel();
//lbl2->setText("Label #2");
//pluginTabs->addTab(lbl2, "L #2; for debugging purposes");
QDir pluginsDir(Rshare::dataDirectory());
// this piece of code is magical and untested ;
// but on Windows it works
#if defined(Q_OS_WIN)
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
pluginsDir.cdUp();
#elif defined(Q_OS_MAC)
if (pluginsDir.dirName() == "MacOS") {
pluginsDir.cdUp();
pluginsDir.cdUp();
pluginsDir.cdUp();
}
#endif
// eof magick
pluginsDir.cd("plugins");
foreach (QString fileName, pluginsDir.entryList(QDir::Files))
{
qDebug() << " "
<< "processing file "
<< pluginsDir.absoluteFilePath(fileName);
QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
QObject *pluginObject = loader.instance();
if (pluginObject)
{
qDebug() << " " << "loaded..." ;
PluginInterface* plugin = qobject_cast<PluginInterface*> (pluginObject) ;
if (plugin)
{
QString pn = plugin->pluginName();
qDebug() << " " << "got description:" << pn;
QWidget* pw = plugin->pluginWidget();
qDebug() << " " << "got widget..." ;
pluginsDir.absoluteFilePath(fileName);
pluginTabs->addTab(pw,pn);
}
else
{
qDebug() << " " << "cast failed..." ;
}
}
}
// script plugins loading; warning, code is dirty; will be changed later
engine = new QScriptEngine;
pluginsDir.cd("../script_plugins");
foreach (QString scriptDirName, pluginsDir.entryList(QDir::Dirs))
{
qDebug() << " " << "sdn is " << scriptDirName ;
if ( (scriptDirName !=".") && (scriptDirName != "..") )
{
QDir spDir(pluginsDir) ;
spDir.cd(scriptDirName);
QStringList scfList = spDir.entryList(QDir::Files) ;
qDebug() << " "
<< "to process files: "
<< scfList ;// pluginsDir.absoluteFilePath(fileName);
int ti;
QRegExp rx_qs(".*js");
ti = scfList.indexOf(rx_qs);
QFile scriptFile( spDir.absoluteFilePath( scfList.at(ti) ) );
scriptFile.open(QIODevice::ReadOnly);
engine->evaluate(scriptFile.readAll());
scriptFile.close();
QUiLoader loader;
QRegExp rx_ui(".*ui");
ti = scfList.indexOf(rx_ui) ;
QFile uiFile( spDir.absoluteFilePath( scfList.at(ti) ) );
qDebug() << "ui file is " << scfList.at(ti) ;
uiFile.open(QIODevice::ReadOnly);
QWidget *ui = loader.load(&uiFile);
uiFile.close();
QScriptValue ctor = engine->evaluate("Plugin");
QScriptValue scriptUi = engine->newQObject(ui, QScriptEngine::ScriptOwnership);
QScriptValue calc = ctor.construct(QScriptValueList() << scriptUi);
if (!ui)
qDebug() << "ui is null :(" ;
//ui->show();
pluginTabs->addTab(ui,"Script plugin");
}
//What has a head like a cat, feet like a cat, a tail like a cat, but isn't a cat?
}
}
//==============================================================================
PluginsPage::~PluginsPage()
{
// nothing to do here at this moment
delete engine;
}

View File

@ -0,0 +1,39 @@
#ifndef _PLUGINS_PAGE_H_
#define _PLUGINS_PAGE_H_
//#include <QFileDialog>
//#include "chat/PopupChatDialog.h"
#include "mainpage.h"
//#include "ui_PeersDialog.h"
class QGroupBox;
class QVBoxLayout;
class QTabWidget;
class QFrame;
class QLabel;
class QScriptEngine;
class PluginsPage : public MainPage
{
Q_OBJECT
public:
/** Default Constructor */
PluginsPage(QWidget *parent = 0);
/** Default Destructor */
~PluginsPage() ;
protected:
QVBoxLayout* pluginPageLayout;
QGroupBox* pluginPanel;
QVBoxLayout* pluginPanelLayout;
QTabWidget* pluginTabs ;
QScriptEngine* engine;
};
#endif

View File

@ -0,0 +1,32 @@
#ifndef _PLUGIN_INTERFACE_H_
#define _PLUGIN_INTERFACE_H_
#include <QtPlugin>
QT_BEGIN_NAMESPACE
class QString;
class QWidget;
QT_END_NAMESPACE
//
class PluginInterface
{
public:
virtual ~PluginInterface() {}
public slots:
virtual QString pluginDescription() const = 0;
virtual QString pluginName() const = 0;
virtual QWidget* pluginWidget(QWidget * parent = 0) = 0;
};
QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(PluginInterface,
"com.beardog.retroshare.PluginInterface/1.0")
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,264 @@
//! [0]
function Plugin(ui)
{
this.ui = ui;
this.pendingAdditiveOperator = "";
this.pendingMultiplicativeOperator = "";
this.sumInMemory = 0;
this.sumSoFar = 0;
this.factorSoFar = 0;
this.waitingForOperand = true;
with (ui) {
display.text = "0";
zeroButton.clicked.connect(this, this.digitClicked);
oneButton.clicked.connect(this, "digitClicked");
twoButton.clicked.connect(this, "digitClicked");
threeButton.clicked.connect(this, "digitClicked");
fourButton.clicked.connect(this, "digitClicked");
fiveButton.clicked.connect(this, "digitClicked");
sixButton.clicked.connect(this, "digitClicked");
sevenButton.clicked.connect(this, "digitClicked");
eightButton.clicked.connect(this, "digitClicked");
nineButton.clicked.connect(this, "digitClicked");
pointButton.clicked.connect(this, "pointClicked");
changeSignButton.clicked.connect(this, "changeSignClicked");
backspaceButton.clicked.connect(this, "backspaceClicked");
clearButton.clicked.connect(this, "clear");
clearAllButton.clicked.connect(this, "clearAll");
clearMemoryButton.clicked.connect(this, "clearMemory");
readMemoryButton.clicked.connect(this, "readMemory");
setMemoryButton.clicked.connect(this, "setMemory");
addToMemoryButton.clicked.connect(this, "addToMemory");
divisionButton.clicked.connect(this, "multiplicativeOperatorClicked");
timesButton.clicked.connect(this, "multiplicativeOperatorClicked");
minusButton.clicked.connect(this, "additiveOperatorClicked");
plusButton.clicked.connect(this, "additiveOperatorClicked");
squareRootButton.clicked.connect(this, "unaryOperatorClicked");
powerButton.clicked.connect(this, "unaryOperatorClicked");
reciprocalButton.clicked.connect(this, "unaryOperatorClicked");
equalButton.clicked.connect(this, "equalClicked");
}
}
//! [0]
Plugin.prototype.abortOperation = function()
{
this.clearAll();
this.ui.display.text = "####";
}
Plugin.prototype.calculate = function(rightOperand, pendingOperator)
{
if (pendingOperator == "+") {
this.sumSoFar += rightOperand;
} else if (pendingOperator == "-") {
this.sumSoFar -= rightOperand;
} else if (pendingOperator == "*") {
this.factorSoFar *= rightOperand;
} else if (pendingOperator == "/") {
if (rightOperand == 0)
return false;
this.factorSoFar /= rightOperand;
}
return true;
}
//! [1]
Plugin.prototype.digitClicked = function()
{
var digitValue = __qt_sender__.text - 0;
if ((digitValue == 0) && (this.ui.display.text == "0"))
return;
if (this.waitingForOperand) {
this.ui.display.clear();
this.waitingForOperand = false;
}
this.ui.display.text += digitValue;
}
//! [1]
Plugin.prototype.unaryOperatorClicked = function()
{
var operand = this.ui.display.text - 0;
var result = 0;
if (__qt_sender__.text == "Sqrt") {
if (operand < 0) {
this.abortOperation();
return;
}
result = Math.sqrt(operand);
} else if (__qt_sender__.text == "x^2") {
result = Math.pow(operand, 2);
} else if (__qt_sender__.text == "1/x") {
if (operand == 0.0) {
this.abortOperation();
return;
}
result = 1 / operand;
}
this.ui.display.text = result + "";
this.waitingForOperand = true;
}
Plugin.prototype.additiveOperatorClicked = function()
{
var operand = this.ui.display.text - 0;
if (this.pendingMultiplicativeOperator.length != 0) {
if (!this.calculate(operand, this.pendingMultiplicativeOperator)) {
this.abortOperation();
return;
}
this.ui.display.text = this.factorSoFar + "";
operand = this.factorSoFar;
this.factorSoFar = 0;
this.pendingMultiplicativeOperator = "";
}
if (this.pendingAdditiveOperator.length != 0) {
if (!this.calculate(operand, this.pendingAdditiveOperator)) {
this.abortOperation();
return;
}
this.ui.display.text = this.sumSoFar + "";
} else {
this.sumSoFar = operand;
}
this.pendingAdditiveOperator = __qt_sender__.text;
this.waitingForOperand = true;
}
Plugin.prototype.multiplicativeOperatorClicked = function()
{
var operand = this.ui.display.text - 0;
if (this.pendingMultiplicativeOperator.length != 0) {
if (!this.calculate(operand, this.pendingMultiplicativeOperator)) {
this.abortOperation();
return;
}
this.ui.display.text = this.factorSoFar + "";
} else {
this.factorSoFar = operand;
}
this.pendingMultiplicativeOperator = __qt_sender__.text;
this.waitingForOperand = true;
}
Plugin.prototype.equalClicked = function()
{
var operand = this.ui.display.text - 0;
if (this.pendingMultiplicativeOperator.length != 0) {
if (!this.calculate(operand, this.pendingMultiplicativeOperator)) {
this.abortOperation();
return;
}
operand = this.factorSoFar;
this.factorSoFar = 0.0;
this.pendingMultiplicativeOperator = "";
}
if (this.pendingAdditiveOperator.length != 0) {
if (!this.calculate(operand, this.pendingAdditiveOperator)) {
this.abortOperation();
return;
}
this.pendingAdditiveOperator = "";
} else {
this.sumSoFar = operand;
}
this.ui.display.text = this.sumSoFar + "";
this.sumSoFar = 0.0;
this.waitingForOperand = true;
}
Plugin.prototype.pointClicked = function()
{
if (this.waitingForOperand)
this.ui.display.text = "0";
if (this.ui.display.text.indexOf(".") == -1)
this.ui.display.text += ".";
this.waitingForOperand = false;
}
//! [2]
Plugin.prototype.changeSignClicked = function()
{
var text = this.ui.display.text;
var value = text - 0;
if (value > 0) {
text = "-" + text;
} else if (value < 0) {
text = text.slice(1);
}
this.ui.display.text = text;
}
//! [2]
Plugin.prototype.backspaceClicked = function()
{
if (this.waitingForOperand)
return;
var text = this.ui.display.text;
text = text.slice(0, -1);
if (text.length == 0) {
text = "0";
this.waitingForOperand = true;
}
this.ui.display.text = text;
}
Plugin.prototype.clear = function()
{
if (this.waitingForOperand)
return;
this.ui.display.text = "0";
this.waitingForOperand = true;
}
Plugin.prototype.clearAll = function()
{
this.sumSoFar = 0.0;
this.factorSoFar = 0.0;
this.pendingAdditiveOperator = "";
this.pendingMultiplicativeOperator = "";
this.ui.display.text = "0";
this.waitingForOperand = true;
}
Plugin.prototype.clearMemory = function()
{
this.sumInMemory = 0.0;
}
Plugin.prototype.readMemory = function()
{
this.ui.display.text = this.sumInMemory + "";
this.waitingForOperand = true;
}
Plugin.prototype.setMemory = function()
{
this.equalClicked();
this.sumInMemory = this.ui.display.text - 0;
}
Plugin.prototype.addToMemory = function()
{
this.equalClicked();
this.sumInMemory += this.ui.display.text - 0;
}

View File

@ -0,0 +1,406 @@
<ui version="4.0" >
<class>Calculator</class>
<widget class="QWidget" name="Calculator" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>314</width>
<height>301</height>
</rect>
</property>
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>314</width>
<height>301</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>314</width>
<height>301</height>
</size>
</property>
<property name="windowTitle" >
<string>Calculator</string>
</property>
<widget class="QToolButton" name="backspaceButton" >
<property name="geometry" >
<rect>
<x>10</x>
<y>50</y>
<width>91</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>Backspace</string>
</property>
</widget>
<widget class="QToolButton" name="clearButton" >
<property name="geometry" >
<rect>
<x>110</x>
<y>50</y>
<width>91</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>Clear :)</string>
</property>
</widget>
<widget class="QToolButton" name="clearAllButton" >
<property name="geometry" >
<rect>
<x>210</x>
<y>50</y>
<width>91</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>Clear All</string>
</property>
</widget>
<widget class="QToolButton" name="clearMemoryButton" >
<property name="geometry" >
<rect>
<x>10</x>
<y>100</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>MC</string>
</property>
</widget>
<widget class="QToolButton" name="readMemoryButton" >
<property name="geometry" >
<rect>
<x>10</x>
<y>150</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>MR</string>
</property>
</widget>
<widget class="QToolButton" name="setMemoryButton" >
<property name="geometry" >
<rect>
<x>10</x>
<y>200</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>MS</string>
</property>
</widget>
<widget class="QToolButton" name="addToMemoryButton" >
<property name="geometry" >
<rect>
<x>10</x>
<y>250</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>M+</string>
</property>
</widget>
<widget class="QToolButton" name="sevenButton" >
<property name="geometry" >
<rect>
<x>60</x>
<y>100</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>7</string>
</property>
</widget>
<widget class="QToolButton" name="eightButton" >
<property name="geometry" >
<rect>
<x>110</x>
<y>100</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>8</string>
</property>
</widget>
<widget class="QToolButton" name="nineButton" >
<property name="geometry" >
<rect>
<x>160</x>
<y>100</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>9</string>
</property>
</widget>
<widget class="QToolButton" name="fourButton" >
<property name="geometry" >
<rect>
<x>60</x>
<y>150</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>4</string>
</property>
</widget>
<widget class="QToolButton" name="fiveButton" >
<property name="geometry" >
<rect>
<x>110</x>
<y>150</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>5</string>
</property>
</widget>
<widget class="QToolButton" name="sixButton" >
<property name="geometry" >
<rect>
<x>160</x>
<y>150</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>6</string>
</property>
</widget>
<widget class="QToolButton" name="oneButton" >
<property name="geometry" >
<rect>
<x>60</x>
<y>200</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>1</string>
</property>
</widget>
<widget class="QToolButton" name="twoButton" >
<property name="geometry" >
<rect>
<x>110</x>
<y>200</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>2</string>
</property>
</widget>
<widget class="QToolButton" name="threeButton" >
<property name="geometry" >
<rect>
<x>160</x>
<y>200</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>3</string>
</property>
</widget>
<widget class="QToolButton" name="zeroButton" >
<property name="geometry" >
<rect>
<x>60</x>
<y>250</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>0</string>
</property>
</widget>
<widget class="QToolButton" name="pointButton" >
<property name="geometry" >
<rect>
<x>110</x>
<y>250</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>.</string>
</property>
</widget>
<widget class="QToolButton" name="changeSignButton" >
<property name="geometry" >
<rect>
<x>160</x>
<y>250</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>+-</string>
</property>
</widget>
<widget class="QToolButton" name="plusButton" >
<property name="geometry" >
<rect>
<x>210</x>
<y>250</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>+</string>
</property>
</widget>
<widget class="QToolButton" name="divisionButton" >
<property name="geometry" >
<rect>
<x>210</x>
<y>100</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>/</string>
</property>
</widget>
<widget class="QToolButton" name="timesButton" >
<property name="geometry" >
<rect>
<x>210</x>
<y>150</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>*</string>
</property>
</widget>
<widget class="QToolButton" name="minusButton" >
<property name="geometry" >
<rect>
<x>210</x>
<y>200</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>-</string>
</property>
</widget>
<widget class="QToolButton" name="squareRootButton" >
<property name="geometry" >
<rect>
<x>260</x>
<y>100</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>Sqrt</string>
</property>
</widget>
<widget class="QToolButton" name="powerButton" >
<property name="geometry" >
<rect>
<x>260</x>
<y>150</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>x^2</string>
</property>
</widget>
<widget class="QToolButton" name="reciprocalButton" >
<property name="geometry" >
<rect>
<x>260</x>
<y>200</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>1/x</string>
</property>
</widget>
<widget class="QToolButton" name="equalButton" >
<property name="geometry" >
<rect>
<x>260</x>
<y>250</y>
<width>41</width>
<height>41</height>
</rect>
</property>
<property name="text" >
<string>=</string>
</property>
</widget>
<widget class="QLineEdit" name="display" >
<property name="geometry" >
<rect>
<x>10</x>
<y>10</y>
<width>291</width>
<height>31</height>
</rect>
</property>
<property name="maxLength" >
<number>15</number>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="readOnly" >
<bool>true</bool>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,28 @@
#=== this part is common (similar) for all plugin projects =====================
TEMPLATE = lib
CONFIG += plugin debug
# this is directory, where PluginInterface.h is located
INCLUDEPATH += ../
# and, the result (*.so or *.dll) should appear in this directory
DESTDIR = ../bin
OBJECTS_DIR = temp/obj
RCC_DIR = temp/qrc
UI_DIR = temp/ui
MOC_DIR = temp/moc
# the name of the result file;
TARGET = $$qtLibraryTarget(calendar_plugin)
HEADERS += ../PluginInterface.h \
src/CalendarPlugin.h
SOURCES += src/CalendarPlugin.cpp
#===============================================================================
#=== and this are definitions, specific for this program =======================
HEADERS += src/mainwindow.h
SOURCES += src/mainwindow.cpp
#===============================================================================

View File

@ -0,0 +1,33 @@
//#include <QApplication>
//#include <QString>
//#include <QPushButton>
#include "CalendarPlugin.h"
#include "mainwindow.h"
QString
CalendarPlugin::pluginDescription() const
{
QString res;
res = "A simple plugin, based on QT calendar(richtext) example" ;
return res;
}
QString
CalendarPlugin::pluginName() const
{
return "Calendar" ;
}
QWidget*
CalendarPlugin::pluginWidget(QWidget * parent )
{
MainWindow* window = new MainWindow(parent);
//window->openImage(":/images/example.jpg");
return window;
}
Q_EXPORT_PLUGIN2(calendar_plugin, CalendarPlugin)

View File

@ -0,0 +1,27 @@
#ifndef _HWA_PLUGIN_H_
#define _HWA_PLUGIN_H_
#include <QObject>
#include <QString>
#include <QWidget>
#include <PluginInterface.h>
#include <QDebug>
class CalendarPlugin: public QObject, public PluginInterface
{
Q_OBJECT
Q_INTERFACES(PluginInterface)
public slots:
virtual QString pluginDescription() const ;
virtual QString pluginName() const ;
virtual QWidget* pluginWidget(QWidget * parent = 0) ;
};
#endif

View File

@ -0,0 +1,213 @@
/****************************************************************************
**
** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the example classes of the Qt Toolkit.
**
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License versions 2.0 or 3.0 as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information
** to ensure GNU General Public Licensing requirements will be met:
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html. In addition, as a special
** exception, Nokia gives you certain additional rights. These rights
** are described in the Nokia Qt GPL Exception version 1.3, included in
** the file GPL_EXCEPTION.txt in this package.
**
** Qt for Windows(R) Licensees
** As a special exception, Nokia, as the sole copyright holder for Qt
** Designer, grants users of the Qt/Eclipse Integration plug-in the
** right for the Qt/Eclipse Integration to link to functionality
** provided by Qt Designer and its related libraries.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
****************************************************************************/
#include <QtGui>
#include "mainwindow.h"
//! [0]
MainWindow::MainWindow(QWidget* parent)
:QFrame(parent)
{
selectedDate = QDate::currentDate();
fontSize = 10;
// QWidget *centralWidget = new QWidget;
//! [0]
//! [1]
QLabel *dateLabel = new QLabel(tr("Date:"));
QComboBox *monthCombo = new QComboBox;
for (int month = 1; month <= 12; ++month)
monthCombo->addItem(QDate::longMonthName(month));
QDateTimeEdit *yearEdit = new QDateTimeEdit;
yearEdit->setDisplayFormat("yyyy");
yearEdit->setDateRange(QDate(1753, 1, 1), QDate(8000, 1, 1));
//! [1]
monthCombo->setCurrentIndex(selectedDate.month() - 1);
yearEdit->setDate(selectedDate);
//! [2]
QLabel *fontSizeLabel = new QLabel(tr("Font size:"));
QSpinBox *fontSizeSpinBox = new QSpinBox;
fontSizeSpinBox->setRange(1, 64);
fontSizeSpinBox->setValue(10);
editor = new QTextBrowser;
insertCalendar();
//! [2]
//! [3]
connect(monthCombo, SIGNAL(activated(int)), this, SLOT(setMonth(int)));
connect(yearEdit, SIGNAL(dateChanged(QDate)), this, SLOT(setYear(QDate)));
connect(fontSizeSpinBox, SIGNAL(valueChanged(int)),
this, SLOT(setFontSize(int)));
//! [3]
//! [4]
QHBoxLayout *controlsLayout = new QHBoxLayout;
controlsLayout->addWidget(dateLabel);
controlsLayout->addWidget(monthCombo);
controlsLayout->addWidget(yearEdit);
controlsLayout->addSpacing(24);
controlsLayout->addWidget(fontSizeLabel);
controlsLayout->addWidget(fontSizeSpinBox);
controlsLayout->addStretch(1);
QVBoxLayout *centralLayout = new QVBoxLayout;
centralLayout->addLayout(controlsLayout);
centralLayout->addWidget(editor, 1);
//centralWidget->setLayout(centralLayout);
this->setLayout(centralLayout);
//setCentralWidget(centralWidget);
//! [4]
}
//! [5]
void MainWindow::insertCalendar()
{
editor->clear();
QTextCursor cursor = editor->textCursor();
cursor.beginEditBlock();
QDate date(selectedDate.year(), selectedDate.month(), 1);
//! [5]
//! [6]
QTextTableFormat tableFormat;
tableFormat.setAlignment(Qt::AlignHCenter);
tableFormat.setBackground(QColor("#e0e0e0"));
tableFormat.setCellPadding(2);
tableFormat.setCellSpacing(4);
//! [6] //! [7]
QVector<QTextLength> constraints;
constraints << QTextLength(QTextLength::PercentageLength, 14)
<< QTextLength(QTextLength::PercentageLength, 14)
<< QTextLength(QTextLength::PercentageLength, 14)
<< QTextLength(QTextLength::PercentageLength, 14)
<< QTextLength(QTextLength::PercentageLength, 14)
<< QTextLength(QTextLength::PercentageLength, 14)
<< QTextLength(QTextLength::PercentageLength, 14);
tableFormat.setColumnWidthConstraints(constraints);
//! [7]
//! [8]
QTextTable *table = cursor.insertTable(1, 7, tableFormat);
//! [8]
//! [9]
QTextFrame *frame = cursor.currentFrame();
QTextFrameFormat frameFormat = frame->frameFormat();
frameFormat.setBorder(1);
frame->setFrameFormat(frameFormat);
//! [9]
//! [10]
QTextCharFormat format = cursor.charFormat();
format.setFontPointSize(fontSize);
QTextCharFormat boldFormat = format;
boldFormat.setFontWeight(QFont::Bold);
QTextCharFormat highlightedFormat = boldFormat;
highlightedFormat.setBackground(Qt::yellow);
//! [10]
//! [11]
for (int weekDay = 1; weekDay <= 7; ++weekDay) {
QTextTableCell cell = table->cellAt(0, weekDay-1);
//! [11] //! [12]
QTextCursor cellCursor = cell.firstCursorPosition();
cellCursor.insertText(QString("%1").arg(QDate::longDayName(weekDay)),
boldFormat);
}
//! [12]
//! [13]
table->insertRows(table->rows(), 1);
//! [13]
while (date.month() == selectedDate.month()) {
int weekDay = date.dayOfWeek();
QTextTableCell cell = table->cellAt(table->rows()-1, weekDay-1);
QTextCursor cellCursor = cell.firstCursorPosition();
if (date == QDate::currentDate())
cellCursor.insertText(QString("%1").arg(date.day()), highlightedFormat);
else
cellCursor.insertText(QString("%1").arg(date.day()), format);
date = date.addDays(1);
if (weekDay == 7 && date.month() == selectedDate.month())
table->insertRows(table->rows(), 1);
}
cursor.endEditBlock();
//! [14]
setWindowTitle(tr("Calendar for %1 %2"
).arg(QDate::longMonthName(selectedDate.month())
).arg(selectedDate.year()));
}
//! [14]
//! [15]
void MainWindow::setFontSize(int size)
{
fontSize = size;
insertCalendar();
}
//! [15]
//! [16]
void MainWindow::setMonth(int month)
{
selectedDate = QDate(selectedDate.year(), month + 1, selectedDate.day());
insertCalendar();
}
//! [16]
//! [17]
void MainWindow::setYear(QDate date)
{
selectedDate = QDate(date.year(), selectedDate.month(), selectedDate.day());
insertCalendar();
}
//! [17]

View File

@ -0,0 +1,71 @@
/****************************************************************************
**
** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the example classes of the Qt Toolkit.
**
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License versions 2.0 or 3.0 as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information
** to ensure GNU General Public Licensing requirements will be met:
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html. In addition, as a special
** exception, Nokia gives you certain additional rights. These rights
** are described in the Nokia Qt GPL Exception version 1.3, included in
** the file GPL_EXCEPTION.txt in this package.
**
** Qt for Windows(R) Licensees
** As a special exception, Nokia, as the sole copyright holder for Qt
** Designer, grants users of the Qt/Eclipse Integration plug-in the
** right for the Qt/Eclipse Integration to link to functionality
** provided by Qt Designer and its related libraries.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
****************************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QDate>
//#include <QMainWindow>
#include <QFrame>
QT_BEGIN_NAMESPACE
class QTextBrowser;
QT_END_NAMESPACE
//! [0]
class MainWindow : public QFrame
{
Q_OBJECT
public:
MainWindow(QWidget* parent);
public slots:
void setFontSize(int size);
void setMonth(int month);
void setYear(QDate date);
private:
void insertCalendar();
int fontSize;
QDate selectedDate;
QTextBrowser *editor;
};
//! [0]
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/images">
<file>example.jpg</file>
</qresource>
</RCC>

View File

@ -0,0 +1,37 @@
#=== this part is common (similar) for all plugin projects =====================
TEMPLATE = lib
CONFIG += plugin debug
# this is directory, where PluginInterface.h is located
INCLUDEPATH += ../
# and, the result (*.so or *.dll) should appear in this directory
DESTDIR = ../bin
OBJECTS_DIR = temp/obj
RCC_DIR = temp/qrc
UI_DIR = temp/ui
MOC_DIR = temp/moc
# the name of the result file;
TARGET = $$qtLibraryTarget(puzzle_plugin)
HEADERS += ../PluginInterface.h \
src/PuzzlePlugin.h
SOURCES += src/PuzzlePlugin.cpp
#===============================================================================
#=== and here are definitions, specific for this program =======================
HEADERS += src/mainwindow.h \
src/pieceslist.h \
src/puzzlewidget.h
RESOURCES = puzzle.qrc
SOURCES += src/mainwindow.cpp \
src/pieceslist.cpp \
src/puzzlewidget.cpp
#===============================================================================

View File

@ -0,0 +1,33 @@
//#include <QApplication>
//#include <QString>
//#include <QPushButton>
#include "PuzzlePlugin.h"
#include "mainwindow.h"
QString
PuzzlePlugin::pluginDescription() const
{
QString res;
res = "A simple plugin, based on QT puzzle example" ;
return res;
}
QString
PuzzlePlugin::pluginName() const
{
return "Puzzle" ;
}
QWidget*
PuzzlePlugin::pluginWidget(QWidget * parent )
{
MainWindow* window = new MainWindow(parent);
window->openImage(":/images/example.jpg");
return window;
}
Q_EXPORT_PLUGIN2(puzzle_plugin, PuzzlePlugin)

View File

@ -0,0 +1,27 @@
#ifndef _HWA_PLUGIN_H_
#define _HWA_PLUGIN_H_
#include <QObject>
#include <QString>
#include <QWidget>
#include <PluginInterface.h>
#include <QDebug>
class PuzzlePlugin: public QObject, public PluginInterface
{
Q_OBJECT
Q_INTERFACES(PluginInterface)
public slots:
virtual QString pluginDescription() const ;
virtual QString pluginName() const ;
virtual QWidget* pluginWidget(QWidget * parent = 0) ;
};
#endif

View File

@ -0,0 +1,160 @@
/****************************************************************************
**
** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the example classes of the Qt Toolkit.
**
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License versions 2.0 or 3.0 as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information
** to ensure GNU General Public Licensing requirements will be met:
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html. In addition, as a special
** exception, Nokia gives you certain additional rights. These rights
** are described in the Nokia Qt GPL Exception version 1.3, included in
** the file GPL_EXCEPTION.txt in this package.
**
** Qt for Windows(R) Licensees
** As a special exception, Nokia, as the sole copyright holder for Qt
** Designer, grants users of the Qt/Eclipse Integration plug-in the
** right for the Qt/Eclipse Integration to link to functionality
** provided by Qt Designer and its related libraries.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
****************************************************************************/
#include <QtGui>
#include <stdlib.h>
#include "mainwindow.h"
#include "pieceslist.h"
#include "puzzlewidget.h"
MainWindow::MainWindow(QWidget *parent)
:QFrame(parent)
//: QMainWindow(parent)
{
//setupMenus();
setupWidgets();
setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
//setWindowTitle(tr("Puzzle"));
}
void MainWindow::openImage(const QString &path)
{
QString fileName = path;
if (fileName.isNull())
fileName = QFileDialog::getOpenFileName(this,
tr("Open Image"), "", "Image Files (*.png *.jpg *.bmp)");
if (!fileName.isEmpty()) {
QPixmap newImage;
if (!newImage.load(fileName)) {
QMessageBox::warning(this, tr("Open Image"),
tr("The image file could not be loaded."),
QMessageBox::Cancel);
return;
}
puzzleImage = newImage;
setupPuzzle();
}
}
void MainWindow::setCompleted()
{
QMessageBox::information(this, tr("Puzzle Completed"),
tr("Congratulations! You have completed the puzzle!\n"
"Click OK to start again."),
QMessageBox::Ok);
setupPuzzle();
}
void MainWindow::setupPuzzle()
{
int size = qMin(puzzleImage.width(), puzzleImage.height());
puzzleImage = puzzleImage.copy((puzzleImage.width() - size)/2,
(puzzleImage.height() - size)/2, size, size).scaled(400,
400, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
piecesList->clear();
for (int y = 0; y < 5; ++y) {
for (int x = 0; x < 5; ++x) {
QPixmap pieceImage = puzzleImage.copy(x*80, y*80, 80, 80);
piecesList->addPiece(pieceImage, QPoint(x, y));
}
}
qsrand(QCursor::pos().x() ^ QCursor::pos().y());
for (int i = 0; i < piecesList->count(); ++i) {
if (int(2.0*qrand()/(RAND_MAX+1.0)) == 1) {
QListWidgetItem *item = piecesList->takeItem(i);
piecesList->insertItem(0, item);
}
}
puzzleWidget->clear();
}
/*
void MainWindow::setupMenus()
{
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
QAction *openAction = fileMenu->addAction(tr("&Open..."));
openAction->setShortcut(QKeySequence(tr("Ctrl+O")));
QAction *exitAction = fileMenu->addAction(tr("E&xit"));
exitAction->setShortcut(QKeySequence(tr("Ctrl+Q")));
QMenu *gameMenu = menuBar()->addMenu(tr("&Game"));
QAction *restartAction = gameMenu->addAction(tr("&Restart"));
connect(openAction, SIGNAL(triggered()), this, SLOT(openImage()));
connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
connect(restartAction, SIGNAL(triggered()), this, SLOT(setupPuzzle()));
}
*/
void MainWindow::setupWidgets()
{/*
QFrame *frame = new QFrame;
QHBoxLayout *frameLayout = new QHBoxLayout(frame);
piecesList = new PiecesList;
puzzleWidget = new PuzzleWidget;
connect(puzzleWidget, SIGNAL(puzzleCompleted()),
this, SLOT(setCompleted()), Qt::QueuedConnection);
frameLayout->addWidget(piecesList);
frameLayout->addWidget(puzzleWidget);
setCentralWidget(frame);
*/
QHBoxLayout *frameLayout = new QHBoxLayout(this);
piecesList = new PiecesList;
puzzleWidget = new PuzzleWidget;
connect(puzzleWidget, SIGNAL(puzzleCompleted()),
this, SLOT(setCompleted()), Qt::QueuedConnection);
frameLayout->addWidget(piecesList);
frameLayout->addWidget(puzzleWidget);
}

View File

@ -0,0 +1,74 @@
/****************************************************************************
**
** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the example classes of the Qt Toolkit.
**
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License versions 2.0 or 3.0 as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information
** to ensure GNU General Public Licensing requirements will be met:
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html. In addition, as a special
** exception, Nokia gives you certain additional rights. These rights
** are described in the Nokia Qt GPL Exception version 1.3, included in
** the file GPL_EXCEPTION.txt in this package.
**
** Qt for Windows(R) Licensees
** As a special exception, Nokia, as the sole copyright holder for Qt
** Designer, grants users of the Qt/Eclipse Integration plug-in the
** right for the Qt/Eclipse Integration to link to functionality
** provided by Qt Designer and its related libraries.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
****************************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QPixmap>
//#include <QMainWindow>
#include <QFrame>
class PiecesList;
class PuzzleWidget;
QT_BEGIN_NAMESPACE
class QListWidgetItem;
QT_END_NAMESPACE
class MainWindow : public QFrame//QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
public slots:
void openImage(const QString &path = QString());
void setupPuzzle();
private slots:
void setCompleted();
private:
//void setupMenus();
void setupWidgets();
QPixmap puzzleImage;
PiecesList *piecesList;
PuzzleWidget *puzzleWidget;
};
#endif

View File

@ -0,0 +1,118 @@
/****************************************************************************
**
** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the example classes of the Qt Toolkit.
**
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License versions 2.0 or 3.0 as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information
** to ensure GNU General Public Licensing requirements will be met:
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html. In addition, as a special
** exception, Nokia gives you certain additional rights. These rights
** are described in the Nokia Qt GPL Exception version 1.3, included in
** the file GPL_EXCEPTION.txt in this package.
**
** Qt for Windows(R) Licensees
** As a special exception, Nokia, as the sole copyright holder for Qt
** Designer, grants users of the Qt/Eclipse Integration plug-in the
** right for the Qt/Eclipse Integration to link to functionality
** provided by Qt Designer and its related libraries.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
****************************************************************************/
#include <QtGui>
#include "pieceslist.h"
PiecesList::PiecesList(QWidget *parent)
: QListWidget(parent)
{
setDragEnabled(true);
setViewMode(QListView::IconMode);
setIconSize(QSize(60, 60));
setSpacing(10);
setAcceptDrops(true);
setDropIndicatorShown(true);
}
void PiecesList::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat("image/x-puzzle-piece"))
event->accept();
else
event->ignore();
}
void PiecesList::dragMoveEvent(QDragMoveEvent *event)
{
if (event->mimeData()->hasFormat("image/x-puzzle-piece")) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else
event->ignore();
}
void PiecesList::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasFormat("image/x-puzzle-piece")) {
QByteArray pieceData = event->mimeData()->data("image/x-puzzle-piece");
QDataStream dataStream(&pieceData, QIODevice::ReadOnly);
QPixmap pixmap;
QPoint location;
dataStream >> pixmap >> location;
addPiece(pixmap, location);
event->setDropAction(Qt::MoveAction);
event->accept();
} else
event->ignore();
}
void PiecesList::addPiece(QPixmap pixmap, QPoint location)
{
QListWidgetItem *pieceItem = new QListWidgetItem(this);
pieceItem->setIcon(QIcon(pixmap));
pieceItem->setData(Qt::UserRole, QVariant(pixmap));
pieceItem->setData(Qt::UserRole+1, location);
pieceItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable
| Qt::ItemIsDragEnabled);
}
void PiecesList::startDrag(Qt::DropActions /*supportedActions*/)
{
QListWidgetItem *item = currentItem();
QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
QPixmap pixmap = qVariantValue<QPixmap>(item->data(Qt::UserRole));
QPoint location = item->data(Qt::UserRole+1).toPoint();
dataStream << pixmap << location;
QMimeData *mimeData = new QMimeData;
mimeData->setData("image/x-puzzle-piece", itemData);
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setHotSpot(QPoint(pixmap.width()/2, pixmap.height()/2));
drag->setPixmap(pixmap);
if (drag->exec(Qt::MoveAction) == Qt::MoveAction)
delete takeItem(row(item));
}

View File

@ -0,0 +1,58 @@
/****************************************************************************
**
** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the example classes of the Qt Toolkit.
**
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License versions 2.0 or 3.0 as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information
** to ensure GNU General Public Licensing requirements will be met:
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html. In addition, as a special
** exception, Nokia gives you certain additional rights. These rights
** are described in the Nokia Qt GPL Exception version 1.3, included in
** the file GPL_EXCEPTION.txt in this package.
**
** Qt for Windows(R) Licensees
** As a special exception, Nokia, as the sole copyright holder for Qt
** Designer, grants users of the Qt/Eclipse Integration plug-in the
** right for the Qt/Eclipse Integration to link to functionality
** provided by Qt Designer and its related libraries.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
****************************************************************************/
#ifndef PIECESLIST_H
#define PIECESLIST_H
#include <QListWidget>
class PiecesList : public QListWidget
{
Q_OBJECT
public:
PiecesList(QWidget *parent = 0);
void addPiece(QPixmap pixmap, QPoint location);
protected:
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
void startDrag(Qt::DropActions supportedActions);
};
#endif

View File

@ -0,0 +1,201 @@
/****************************************************************************
**
** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the example classes of the Qt Toolkit.
**
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License versions 2.0 or 3.0 as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information
** to ensure GNU General Public Licensing requirements will be met:
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html. In addition, as a special
** exception, Nokia gives you certain additional rights. These rights
** are described in the Nokia Qt GPL Exception version 1.3, included in
** the file GPL_EXCEPTION.txt in this package.
**
** Qt for Windows(R) Licensees
** As a special exception, Nokia, as the sole copyright holder for Qt
** Designer, grants users of the Qt/Eclipse Integration plug-in the
** right for the Qt/Eclipse Integration to link to functionality
** provided by Qt Designer and its related libraries.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
****************************************************************************/
#include <QtGui>
#include "puzzlewidget.h"
PuzzleWidget::PuzzleWidget(QWidget *parent)
: QWidget(parent)
{
setAcceptDrops(true);
setMinimumSize(400, 400);
setMaximumSize(400, 400);
}
void PuzzleWidget::clear()
{
pieceLocations.clear();
piecePixmaps.clear();
pieceRects.clear();
highlightedRect = QRect();
inPlace = 0;
update();
}
void PuzzleWidget::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat("image/x-puzzle-piece"))
event->accept();
else
event->ignore();
}
void PuzzleWidget::dragLeaveEvent(QDragLeaveEvent *event)
{
QRect updateRect = highlightedRect;
highlightedRect = QRect();
update(updateRect);
event->accept();
}
void PuzzleWidget::dragMoveEvent(QDragMoveEvent *event)
{
QRect updateRect = highlightedRect.unite(targetSquare(event->pos()));
if (event->mimeData()->hasFormat("image/x-puzzle-piece")
&& findPiece(targetSquare(event->pos())) == -1) {
highlightedRect = targetSquare(event->pos());
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
highlightedRect = QRect();
event->ignore();
}
update(updateRect);
}
void PuzzleWidget::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasFormat("image/x-puzzle-piece")
&& findPiece(targetSquare(event->pos())) == -1) {
QByteArray pieceData = event->mimeData()->data("image/x-puzzle-piece");
QDataStream dataStream(&pieceData, QIODevice::ReadOnly);
QRect square = targetSquare(event->pos());
QPixmap pixmap;
QPoint location;
dataStream >> pixmap >> location;
pieceLocations.append(location);
piecePixmaps.append(pixmap);
pieceRects.append(square);
highlightedRect = QRect();
update(square);
event->setDropAction(Qt::MoveAction);
event->accept();
if (location == QPoint(square.x()/80, square.y()/80)) {
inPlace++;
if (inPlace == 25)
emit puzzleCompleted();
}
} else {
highlightedRect = QRect();
event->ignore();
}
}
int PuzzleWidget::findPiece(const QRect &pieceRect) const
{
for (int i = 0; i < pieceRects.size(); ++i) {
if (pieceRect == pieceRects[i]) {
return i;
}
}
return -1;
}
void PuzzleWidget::mousePressEvent(QMouseEvent *event)
{
QRect square = targetSquare(event->pos());
int found = findPiece(square);
if (found == -1)
return;
QPoint location = pieceLocations[found];
QPixmap pixmap = piecePixmaps[found];
pieceLocations.removeAt(found);
piecePixmaps.removeAt(found);
pieceRects.removeAt(found);
if (location == QPoint(square.x()/80, square.y()/80))
inPlace--;
update(square);
QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << pixmap << location;
QMimeData *mimeData = new QMimeData;
mimeData->setData("image/x-puzzle-piece", itemData);
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setHotSpot(event->pos() - square.topLeft());
drag->setPixmap(pixmap);
if (!(drag->exec(Qt::MoveAction) == Qt::MoveAction)) {
pieceLocations.insert(found, location);
piecePixmaps.insert(found, pixmap);
pieceRects.insert(found, square);
update(targetSquare(event->pos()));
if (location == QPoint(square.x()/80, square.y()/80))
inPlace++;
}
}
void PuzzleWidget::paintEvent(QPaintEvent *event)
{
QPainter painter;
painter.begin(this);
painter.fillRect(event->rect(), Qt::white);
if (highlightedRect.isValid()) {
painter.setBrush(QColor("#ffcccc"));
painter.setPen(Qt::NoPen);
painter.drawRect(highlightedRect.adjusted(0, 0, -1, -1));
}
for (int i = 0; i < pieceRects.size(); ++i) {
painter.drawPixmap(pieceRects[i], piecePixmaps[i]);
}
painter.end();
}
const QRect PuzzleWidget::targetSquare(const QPoint &position) const
{
return QRect(position.x()/80 * 80, position.y()/80 * 80, 80, 80);
}

View File

@ -0,0 +1,82 @@
/****************************************************************************
**
** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the example classes of the Qt Toolkit.
**
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License versions 2.0 or 3.0 as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information
** to ensure GNU General Public Licensing requirements will be met:
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html. In addition, as a special
** exception, Nokia gives you certain additional rights. These rights
** are described in the Nokia Qt GPL Exception version 1.3, included in
** the file GPL_EXCEPTION.txt in this package.
**
** Qt for Windows(R) Licensees
** As a special exception, Nokia, as the sole copyright holder for Qt
** Designer, grants users of the Qt/Eclipse Integration plug-in the
** right for the Qt/Eclipse Integration to link to functionality
** provided by Qt Designer and its related libraries.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
****************************************************************************/
#ifndef PUZZLEWIDGET_H
#define PUZZLEWIDGET_H
#include <QList>
#include <QPoint>
#include <QPixmap>
#include <QWidget>
QT_BEGIN_NAMESPACE
class QDragEnterEvent;
class QDropEvent;
class QMouseEvent;
QT_END_NAMESPACE
class PuzzleWidget : public QWidget
{
Q_OBJECT
public:
PuzzleWidget(QWidget *parent = 0);
void clear();
signals:
void puzzleCompleted();
protected:
void dragEnterEvent(QDragEnterEvent *event);
void dragLeaveEvent(QDragLeaveEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
void mousePressEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
private:
int findPiece(const QRect &pieceRect) const;
const QRect targetSquare(const QPoint &position) const;
QList<QPixmap> piecePixmaps;
QList<QRect> pieceRects;
QList<QPoint> pieceLocations;
QRect highlightedRect;
int inPlace;
};
#endif