[4] | 1 | #include <QImage> |
---|
| 2 | #include <QPainter> |
---|
| 3 | #include <QGLPixelBuffer> |
---|
| 4 | |
---|
| 5 | #include "Scene.h" |
---|
| 6 | #include "Screen.h" |
---|
| 7 | #include "Channel.h" |
---|
| 8 | #include "RSync.h" |
---|
| 9 | #include "Exporter.h" |
---|
| 10 | #include "GUIControler.h" |
---|
| 11 | |
---|
| 12 | #include "ProjectionModel.h" |
---|
| 13 | |
---|
| 14 | using namespace projection; |
---|
| 15 | |
---|
| 16 | QDir ProjectionModel::pluginsDir; |
---|
| 17 | QStringList ProjectionModel::pluginFileNames; |
---|
| 18 | QList<ProjectorInterface*> ProjectionModel::projector_interfaces; |
---|
| 19 | QList<SceneInterface*> ProjectionModel::scene_interfaces; |
---|
| 20 | |
---|
| 21 | Q_IMPORT_PLUGIN(projdesigner_default) |
---|
| 22 | |
---|
| 23 | /** |
---|
| 24 | * Constructor. |
---|
| 25 | */ |
---|
| 26 | ProjectionModel::ProjectionModel() : QObject() |
---|
| 27 | { |
---|
| 28 | loadPlugins(); |
---|
| 29 | |
---|
| 30 | m_pScene = new Scene(this); |
---|
| 31 | m_pScreen = new Screen(this); |
---|
| 32 | |
---|
| 33 | m_pSelectedChannel = NULL; |
---|
| 34 | |
---|
| 35 | m_projectorAreaTexIndex = 0; |
---|
| 36 | m_viewAreaTexIndex = 0; |
---|
| 37 | |
---|
| 38 | m_designMode = DESIGN_MODE_DISTORTIONMAP; |
---|
| 39 | |
---|
| 40 | m_bBlockUpdate = false; |
---|
| 41 | |
---|
| 42 | m_pRSync = new RSync(this); |
---|
| 43 | m_pExporter = new Exporter(this); |
---|
| 44 | m_pGUI = new GUIControler(this); |
---|
| 45 | |
---|
| 46 | m_pGLWidget = NULL; |
---|
| 47 | m_pPBuffer = NULL; |
---|
| 48 | |
---|
| 49 | #ifdef _DEBUG |
---|
| 50 | m_updateViewsCount = 0; |
---|
| 51 | m_updateOffscreenCount = 0; |
---|
| 52 | #endif // _DEBUG |
---|
| 53 | } |
---|
| 54 | |
---|
| 55 | /** |
---|
| 56 | * Destructor. |
---|
| 57 | */ |
---|
| 58 | ProjectionModel::~ProjectionModel() |
---|
| 59 | { |
---|
| 60 | if (glIsTexture(m_projectorAreaTexIndex)) |
---|
| 61 | glDeleteTextures(1, &m_projectorAreaTexIndex); |
---|
| 62 | if (m_pRSync->isServer()) |
---|
| 63 | { |
---|
| 64 | while (getNumChannels() > 0) |
---|
| 65 | removeChannel(0); |
---|
| 66 | } |
---|
| 67 | delete m_pScreen; |
---|
| 68 | delete m_pScene; |
---|
| 69 | |
---|
| 70 | delete m_pRSync; |
---|
| 71 | delete m_pExporter; |
---|
| 72 | delete m_pGUI; |
---|
| 73 | } |
---|
| 74 | |
---|
| 75 | /** |
---|
| 76 | * Initialize as a server. |
---|
| 77 | * |
---|
| 78 | * @param portNo Port number. |
---|
| 79 | */ |
---|
| 80 | void ProjectionModel::initServer(int portNo) |
---|
| 81 | { |
---|
| 82 | m_pRSync->initServer(portNo); |
---|
| 83 | m_pGUI->init(true); |
---|
| 84 | } |
---|
| 85 | |
---|
| 86 | /** |
---|
| 87 | * Initialize as a client. |
---|
| 88 | * |
---|
| 89 | * @param address Client address. |
---|
| 90 | * @param portNo Port number. |
---|
| 91 | */ |
---|
| 92 | void ProjectionModel::initClient(const QString& address, int portNo) |
---|
| 93 | { |
---|
| 94 | m_pRSync->initClient(address, portNo); |
---|
| 95 | m_pGUI->init(false); |
---|
| 96 | } |
---|
| 97 | |
---|
| 98 | /** |
---|
| 99 | * Add a new channel. |
---|
| 100 | * |
---|
| 101 | * @return New channel. |
---|
| 102 | */ |
---|
| 103 | Channel* ProjectionModel::addChannel() |
---|
| 104 | { |
---|
| 105 | Channel* pChannel = new Channel(this); |
---|
| 106 | if (m_pSelectedChannel) |
---|
| 107 | *pChannel = *m_pSelectedChannel; |
---|
| 108 | m_pChannels.push_back(pChannel); |
---|
| 109 | |
---|
| 110 | return pChannel; |
---|
| 111 | } |
---|
| 112 | |
---|
| 113 | /** |
---|
| 114 | * Retrieve the number of the channels. |
---|
| 115 | * |
---|
| 116 | * @return The number of the channels. |
---|
| 117 | */ |
---|
| 118 | unsigned int ProjectionModel::getNumChannels() const |
---|
| 119 | { |
---|
| 120 | return m_pChannels.size(); |
---|
| 121 | } |
---|
| 122 | |
---|
| 123 | /** |
---|
| 124 | * Retrieve a channel object |
---|
| 125 | * |
---|
| 126 | * @param index Index of channel to retrieve. |
---|
| 127 | * @return Channel object. |
---|
| 128 | */ |
---|
| 129 | Channel* ProjectionModel::getChannel(int index) const |
---|
| 130 | { |
---|
| 131 | if (index >= 0 && index < m_pChannels.size()) |
---|
| 132 | return m_pChannels[index]; |
---|
| 133 | return NULL; |
---|
| 134 | |
---|
| 135 | } |
---|
| 136 | |
---|
| 137 | /** |
---|
| 138 | * Retrieve Index of the specified channel. |
---|
| 139 | * |
---|
| 140 | * @param pChannel Channel object. |
---|
| 141 | * @return Index of the specified channel. |
---|
| 142 | */ |
---|
| 143 | int ProjectionModel::getChannelIndex(Channel* pChannel) const |
---|
| 144 | { |
---|
| 145 | for (int i=0; i<m_pChannels.size(); ++i) |
---|
| 146 | if (m_pChannels[i] == pChannel) |
---|
| 147 | return i; |
---|
| 148 | return -1; |
---|
| 149 | } |
---|
| 150 | |
---|
| 151 | /** |
---|
| 152 | * Remove the specified channel. |
---|
| 153 | * |
---|
| 154 | * @param index Index of the channel to remove. |
---|
| 155 | */ |
---|
| 156 | void ProjectionModel::removeChannel(int index) |
---|
| 157 | { |
---|
| 158 | if (index < 0) |
---|
| 159 | return; |
---|
| 160 | |
---|
| 161 | Channel* pChannel = m_pChannels.takeAt(index); |
---|
| 162 | if (m_pSelectedChannel == pChannel) { |
---|
| 163 | m_pGUI->selectChannel(NULL); |
---|
| 164 | m_pSelectedChannel = NULL; |
---|
| 165 | } |
---|
| 166 | if (pChannel) { |
---|
| 167 | m_pGUI->removeChannel(pChannel); |
---|
| 168 | delete pChannel; |
---|
| 169 | } |
---|
| 170 | |
---|
| 171 | updateViews(); |
---|
| 172 | } |
---|
| 173 | |
---|
| 174 | /** |
---|
| 175 | * Remove all channels. |
---|
| 176 | */ |
---|
| 177 | void ProjectionModel::removeAllChannels() |
---|
| 178 | { |
---|
| 179 | m_pSelectedChannel = NULL; |
---|
| 180 | m_pGUI->selectChannel(NULL); |
---|
| 181 | |
---|
| 182 | while (getNumChannels() > 0) |
---|
| 183 | removeChannel(0); |
---|
| 184 | |
---|
| 185 | m_pGUI->updateGUI(); |
---|
| 186 | } |
---|
| 187 | |
---|
| 188 | /** |
---|
| 189 | * Select a channel. |
---|
| 190 | * |
---|
| 191 | * @param pChannel Channel object to select. |
---|
| 192 | */ |
---|
| 193 | void ProjectionModel::selectChannel(Channel* pChannel) |
---|
| 194 | { |
---|
| 195 | if (m_pSelectedChannel != pChannel) |
---|
| 196 | { |
---|
| 197 | m_pSelectedChannel = pChannel; |
---|
| 198 | m_pGUI->selectChannel(pChannel); |
---|
| 199 | updateViews(); |
---|
| 200 | } |
---|
| 201 | } |
---|
| 202 | |
---|
| 203 | /** |
---|
| 204 | * Retrieve the selected channel object. |
---|
| 205 | * |
---|
| 206 | * @return Selected channel object. |
---|
| 207 | */ |
---|
| 208 | Channel* ProjectionModel::getSelectedChannel() const |
---|
| 209 | { |
---|
| 210 | return m_pSelectedChannel; |
---|
| 211 | } |
---|
| 212 | |
---|
| 213 | /** |
---|
| 214 | * Select the previous channel. |
---|
| 215 | */ |
---|
| 216 | void ProjectionModel::selectPreviousChannel() |
---|
| 217 | { |
---|
| 218 | if (m_pChannels.size() == 0) return; |
---|
| 219 | |
---|
| 220 | if (m_pSelectedChannel) |
---|
| 221 | selectChannel(getChannel((getChannelIndex(m_pSelectedChannel)-1)%getNumChannels())); |
---|
| 222 | else |
---|
| 223 | selectChannel(getChannel(getNumChannels()-1)); |
---|
| 224 | } |
---|
| 225 | |
---|
| 226 | /** |
---|
| 227 | * Select the next channel. |
---|
| 228 | */ |
---|
| 229 | void ProjectionModel::selectNextChannel() |
---|
| 230 | { |
---|
| 231 | if (m_pChannels.size() == 0) return; |
---|
| 232 | |
---|
| 233 | if (m_pSelectedChannel) |
---|
| 234 | selectChannel(getChannel((getChannelIndex(m_pSelectedChannel)+1)%getNumChannels())); |
---|
| 235 | else |
---|
| 236 | selectChannel(getChannel(0)); |
---|
| 237 | } |
---|
| 238 | |
---|
| 239 | /** |
---|
| 240 | * Check whether any channels with the specified name is existing or not. |
---|
| 241 | * |
---|
| 242 | * @return True if a channel with the specified name is existing. |
---|
| 243 | */ |
---|
| 244 | bool ProjectionModel::hasChannel(const QString& name) const |
---|
| 245 | { |
---|
| 246 | for (int i=0; i<m_pChannels.size(); ++i) |
---|
| 247 | if (m_pChannels.at(i)->getName() == name) |
---|
| 248 | return true; |
---|
| 249 | return false; |
---|
| 250 | } |
---|
| 251 | |
---|
| 252 | /** |
---|
| 253 | * Create a unique name for specified channel. |
---|
| 254 | * |
---|
| 255 | * @param name Candidate name of channel. It may not be a unique name. |
---|
| 256 | * @param pChannel Channel object to give a name. |
---|
| 257 | * @return Unique name for the specified channel. |
---|
| 258 | */ |
---|
| 259 | QString ProjectionModel::getUniqueName(const QString& name, Channel* pChannel) const |
---|
| 260 | { |
---|
| 261 | bool bUnique = true; |
---|
| 262 | int i; |
---|
| 263 | for (i=0; i<m_pChannels.size(); ++i) |
---|
| 264 | if (m_pChannels[i] != pChannel && m_pChannels[i]->getName() == name) |
---|
| 265 | bUnique = false; |
---|
| 266 | if (!bUnique) { |
---|
| 267 | int count = 0; |
---|
| 268 | QString uniqueName; |
---|
| 269 | while (true) { |
---|
| 270 | uniqueName = name + QString("_%1").arg(count); |
---|
| 271 | bUnique = true; |
---|
| 272 | for (i=0; i<m_pChannels.size(); ++i) |
---|
| 273 | if (m_pChannels[i]->getName() == uniqueName) |
---|
| 274 | bUnique = false; |
---|
| 275 | if (bUnique) break; |
---|
| 276 | count++; |
---|
| 277 | } |
---|
| 278 | return uniqueName; |
---|
| 279 | } |
---|
| 280 | |
---|
| 281 | return name; |
---|
| 282 | } |
---|
| 283 | |
---|
| 284 | /** |
---|
| 285 | * Create a projection area texture and retrieve its texture object index. |
---|
| 286 | * |
---|
| 287 | * @return Texture object index of the projection area texture. |
---|
| 288 | */ |
---|
| 289 | GLuint ProjectionModel::getProjectorAreaTexture() |
---|
| 290 | { |
---|
| 291 | if (m_projectorAreaTexIndex == 0) |
---|
| 292 | { |
---|
| 293 | QPixmap pixmap(256, 256); |
---|
| 294 | pixmap.fill(QColor(0, 0, 64)); |
---|
| 295 | QPainter painter(&pixmap); |
---|
| 296 | painter.setPen(QColor(255, 255, 255)); |
---|
| 297 | painter.drawRect(0, 0, 255, 255); |
---|
| 298 | m_projectorAreaTexIndex = getGUI()->getGLWidget()->bindTexture(pixmap); |
---|
| 299 | } |
---|
| 300 | return m_projectorAreaTexIndex; |
---|
| 301 | } |
---|
| 302 | |
---|
| 303 | /** |
---|
| 304 | * Create a view area texture and retrieve its texture object index. |
---|
| 305 | * |
---|
| 306 | * @return Texture object index of the view area texture. |
---|
| 307 | */ |
---|
| 308 | GLuint ProjectionModel::getViewAreaTexture() |
---|
| 309 | { |
---|
| 310 | if (m_viewAreaTexIndex == 0) |
---|
| 311 | { |
---|
| 312 | QPixmap pixmap(256, 256); |
---|
| 313 | pixmap.fill(QColor(64, 64, 0)); |
---|
| 314 | QPainter painter(&pixmap); |
---|
| 315 | painter.setPen(QColor(255, 255, 255)); |
---|
| 316 | painter.drawRect(0, 0, 255, 255); |
---|
| 317 | m_viewAreaTexIndex = getGUI()->getGLWidget()->bindTexture(pixmap); |
---|
| 318 | } |
---|
| 319 | return m_viewAreaTexIndex; |
---|
| 320 | } |
---|
| 321 | |
---|
| 322 | /** |
---|
| 323 | * Set design mode. |
---|
| 324 | * |
---|
| 325 | * @param designMode Design mode. |
---|
| 326 | */ |
---|
| 327 | void ProjectionModel::setDesignMode(DESIGN_MODE designMode) |
---|
| 328 | { |
---|
| 329 | if (m_designMode != designMode) |
---|
| 330 | { |
---|
| 331 | m_designMode = designMode; |
---|
| 332 | updateViews(); |
---|
| 333 | |
---|
| 334 | QDomDocument doc; |
---|
| 335 | doc.appendChild(domElement("Model", doc)); |
---|
| 336 | getRSync()->sendChanges(RSYNC_COMMAND_MODEL, doc.toString(0)); |
---|
| 337 | } |
---|
| 338 | } |
---|
| 339 | |
---|
| 340 | /** |
---|
| 341 | * Retrieve the current design mode. |
---|
| 342 | * |
---|
| 343 | * @param designMode Design mode. |
---|
| 344 | */ |
---|
| 345 | DESIGN_MODE ProjectionModel::getDesignMode() const |
---|
| 346 | { |
---|
| 347 | return m_designMode; |
---|
| 348 | } |
---|
| 349 | |
---|
| 350 | /** |
---|
| 351 | * Block or unblock to update views. |
---|
| 352 | * |
---|
| 353 | * @param bBlock True to block updating views. |
---|
| 354 | */ |
---|
| 355 | void ProjectionModel::setBlockUpdate(bool bBlock) |
---|
| 356 | { |
---|
| 357 | m_bBlockUpdate = bBlock; |
---|
| 358 | } |
---|
| 359 | |
---|
| 360 | /** |
---|
| 361 | * Check whether blocking or not update views. |
---|
| 362 | * |
---|
| 363 | * @return True if blocking to update views. |
---|
| 364 | */ |
---|
| 365 | bool ProjectionModel::getBlockUpdate() const |
---|
| 366 | { |
---|
| 367 | return m_bBlockUpdate; |
---|
| 368 | } |
---|
| 369 | |
---|
| 370 | /** |
---|
| 371 | * Redraw all views (DesignViewWindow and ProjectorWindows). |
---|
| 372 | */ |
---|
| 373 | void ProjectionModel::updateViews() |
---|
| 374 | { |
---|
| 375 | #ifdef _DEBUG |
---|
| 376 | m_updateViewsCount++; |
---|
| 377 | #endif // _DEBUG |
---|
| 378 | |
---|
| 379 | if (!m_bBlockUpdate) |
---|
| 380 | m_pGUI->updateViews(); |
---|
| 381 | } |
---|
| 382 | |
---|
| 383 | /** |
---|
| 384 | * Redraw off-screen buffer of the specified channel, then redraw all views. |
---|
| 385 | */ |
---|
| 386 | void ProjectionModel::updateViewAndOffscreens() |
---|
| 387 | { |
---|
| 388 | #ifdef _DEBUG |
---|
| 389 | m_updateOffscreenCount++; |
---|
| 390 | #endif // _DEBUG |
---|
| 391 | |
---|
| 392 | for (int i=0; i<m_pChannels.size(); ++i) |
---|
| 393 | m_pChannels[i]->renderSceneToViewBuffer(); |
---|
| 394 | |
---|
| 395 | if (!m_bBlockUpdate) |
---|
| 396 | m_pGUI->updateViews(); |
---|
| 397 | } |
---|
| 398 | |
---|
| 399 | /** |
---|
| 400 | * Load projection settings from a file. |
---|
| 401 | * |
---|
| 402 | * @param fileName File name to load. |
---|
| 403 | * @return True if successfully loaded. |
---|
| 404 | */ |
---|
| 405 | bool ProjectionModel::loadFile(const QString& fileName) |
---|
| 406 | { |
---|
| 407 | QFile file(fileName); |
---|
| 408 | if (!file.open(QIODevice::ReadOnly)) |
---|
| 409 | return false; |
---|
| 410 | |
---|
| 411 | QDomDocument doc; |
---|
| 412 | doc.setContent(&file); |
---|
| 413 | file.close(); |
---|
| 414 | |
---|
| 415 | if(!restoreSettings(doc)) |
---|
| 416 | return false; |
---|
| 417 | |
---|
| 418 | return true; |
---|
| 419 | } |
---|
| 420 | |
---|
| 421 | /** |
---|
| 422 | * Save the current projection settings to a file. |
---|
| 423 | * |
---|
| 424 | * @param fileName File name to save. |
---|
| 425 | * @return True if successfully saved. |
---|
| 426 | */ |
---|
| 427 | bool ProjectionModel::saveFile(const QString& fileName) |
---|
| 428 | { |
---|
| 429 | QFile file(fileName); |
---|
| 430 | if (file.open(QIODevice::WriteOnly|QIODevice::Truncate)) |
---|
| 431 | { |
---|
| 432 | QTextStream out(&file); |
---|
| 433 | QDomDocument doc; |
---|
| 434 | |
---|
| 435 | storeSettings(doc); |
---|
| 436 | |
---|
| 437 | doc.save(out, 4); |
---|
| 438 | file.flush(); |
---|
| 439 | file.close(); |
---|
| 440 | |
---|
| 441 | return true; |
---|
| 442 | } |
---|
| 443 | return false; |
---|
| 444 | } |
---|
| 445 | |
---|
| 446 | /** |
---|
| 447 | * Restart from a new file. |
---|
| 448 | * |
---|
| 449 | * @return True if everything is ok. |
---|
| 450 | */ |
---|
| 451 | bool ProjectionModel::newFile() |
---|
| 452 | { |
---|
| 453 | QDomDocument doc; |
---|
| 454 | doc.setContent(QString("")); |
---|
| 455 | restoreSettings(doc); |
---|
| 456 | return true; |
---|
| 457 | } |
---|
| 458 | |
---|
| 459 | /** |
---|
| 460 | * Restore the model from XML data. |
---|
| 461 | * |
---|
| 462 | * @param element Parent XML element of the model data. |
---|
| 463 | */ |
---|
| 464 | bool ProjectionModel::initFromDOMElement(const QDomElement& element) |
---|
| 465 | { |
---|
| 466 | if (!element.isNull()) |
---|
| 467 | { |
---|
| 468 | if (element.attribute("designMode") == "distortionMap") |
---|
| 469 | setDesignMode(DESIGN_MODE_DISTORTIONMAP); |
---|
| 470 | else |
---|
| 471 | setDesignMode(DESIGN_MODE_BLENDMAP); |
---|
| 472 | } |
---|
| 473 | |
---|
| 474 | return true; // Todo: Secure this funtion and return only true if no critical error occurs |
---|
| 475 | } |
---|
| 476 | |
---|
| 477 | /** |
---|
| 478 | * Store the current model as XML data. |
---|
| 479 | * |
---|
| 480 | * @param name XML node name of the data. |
---|
| 481 | * @param doc XML document to store the data. |
---|
| 482 | * @return Current screen data as XML data. |
---|
| 483 | */ |
---|
| 484 | QDomElement ProjectionModel::domElement(const QString& name, QDomDocument& doc) const |
---|
| 485 | { |
---|
| 486 | QDomElement de = doc.createElement(name); |
---|
| 487 | de.setAttribute("designMode", m_designMode==DESIGN_MODE_DISTORTIONMAP?"distortionMap":"blendMap"); |
---|
| 488 | |
---|
| 489 | return de; |
---|
| 490 | } |
---|
| 491 | |
---|
| 492 | /** |
---|
| 493 | * Restore projection settings from xml data. |
---|
| 494 | * |
---|
| 495 | * @param doc XML document to restore the projection settings from. |
---|
| 496 | */ |
---|
| 497 | bool ProjectionModel::restoreSettings(QDomDocument& doc) |
---|
| 498 | { |
---|
| 499 | // separate from environment (cocoon) |
---|
| 500 | blockSignals(true); |
---|
| 501 | m_pRSync->setBlockSync(true); |
---|
| 502 | |
---|
| 503 | // Deleting old Channels |
---|
| 504 | while (getNumChannels() > 0) |
---|
| 505 | removeChannel(0); |
---|
| 506 | |
---|
| 507 | // ?? |
---|
| 508 | QDomElement main; |
---|
| 509 | main = doc.documentElement(); |
---|
| 510 | |
---|
| 511 | // Setting data version |
---|
| 512 | QString version = main.attribute("version"); |
---|
| 513 | if (version.isNull()) version="1.0.0"; |
---|
| 514 | |
---|
| 515 | // Initialising channels |
---|
| 516 | QDomElement channel = main.firstChildElement("Channel"); |
---|
| 517 | while (!channel.isNull()) { |
---|
| 518 | Channel* pChannel = addChannel(); |
---|
| 519 | if( !pChannel->initFromDOMElement(channel, version) ) |
---|
| 520 | return false; |
---|
| 521 | channel = channel.nextSiblingElement("Channel"); |
---|
| 522 | } |
---|
| 523 | |
---|
| 524 | // Now initializing other parts (its important that the channels are initialized first, because then sync to remote channels is possible.) |
---|
| 525 | if( !initFromDOMElement(main.firstChildElement("Model")) ) |
---|
| 526 | return false; |
---|
| 527 | if( !m_pScene->initFromDOMElement(main.firstChildElement("Scene")) ) |
---|
| 528 | return false; |
---|
| 529 | if( !m_pScreen->initFromDOMElement(main.firstChildElement("Screen")) ) |
---|
| 530 | return false; |
---|
| 531 | if( !m_pExporter->initFromDOMElement(main.firstChildElement("Exporter")) ) |
---|
| 532 | return false; |
---|
| 533 | |
---|
| 534 | |
---|
| 535 | if (m_pRSync->isServer()) |
---|
| 536 | { |
---|
| 537 | if (!main.firstChildElement("GUI").isNull()) |
---|
| 538 | if( !m_pGUI->initFromDOMElement(main.firstChildElement("GUI")) ) |
---|
| 539 | return false; |
---|
| 540 | m_pGUI->updateGUI(); |
---|
| 541 | } |
---|
| 542 | |
---|
| 543 | // Reopen to environment :) |
---|
| 544 | m_pRSync->setBlockSync(false); |
---|
| 545 | |
---|
| 546 | m_pRSync->sendReloadSettings(); // <== Function secured: is only performed when server |
---|
| 547 | |
---|
| 548 | // Reopen to environment :) |
---|
| 549 | blockSignals(false); |
---|
| 550 | |
---|
| 551 | selectNextChannel(); |
---|
| 552 | |
---|
| 553 | updateViewAndOffscreens(); |
---|
| 554 | |
---|
| 555 | return true; |
---|
| 556 | } |
---|
| 557 | |
---|
| 558 | /** |
---|
| 559 | * Store projection settings to xml data. |
---|
| 560 | * |
---|
| 561 | * @param doc XML document to store the projection settings. |
---|
| 562 | */ |
---|
| 563 | void ProjectionModel::storeSettings(QDomDocument& doc) |
---|
| 564 | { |
---|
| 565 | QDomElement main = doc.createElement("Distortion"); |
---|
| 566 | |
---|
| 567 | main.setAttribute("version", APPLICATION_VERSION); |
---|
| 568 | |
---|
| 569 | main.appendChild(domElement("Model", doc)); |
---|
| 570 | main.appendChild(m_pExporter->domElement("Exporter", doc)); |
---|
| 571 | main.appendChild(m_pScene->domElement("Scene", doc)); |
---|
| 572 | main.appendChild(m_pScreen->domElement("Screen", doc)); |
---|
| 573 | main.appendChild(m_pExporter->domElement("Exporter", doc)); |
---|
| 574 | for (int i=0; i<m_pChannels.size(); ++i) |
---|
| 575 | main.appendChild(m_pChannels[i]->domElement("Channel", doc)); |
---|
| 576 | |
---|
| 577 | main.appendChild(m_pGUI->domElement("GUI", doc)); |
---|
| 578 | |
---|
| 579 | doc.appendChild(main); |
---|
| 580 | } |
---|
| 581 | |
---|
| 582 | /** |
---|
| 583 | * Retrieve the scene object. |
---|
| 584 | * |
---|
| 585 | * @return Scene object. |
---|
| 586 | */ |
---|
| 587 | Scene* ProjectionModel::getScene() const |
---|
| 588 | { |
---|
| 589 | return m_pScene; |
---|
| 590 | } |
---|
| 591 | |
---|
| 592 | /** |
---|
| 593 | * Retrieve the screen object. |
---|
| 594 | * |
---|
| 595 | * @return Screen object. |
---|
| 596 | */ |
---|
| 597 | Screen* ProjectionModel::getScreen() const |
---|
| 598 | { |
---|
| 599 | return m_pScreen; |
---|
| 600 | } |
---|
| 601 | |
---|
| 602 | /** |
---|
| 603 | * Retrieve the remote state synchronize object. |
---|
| 604 | * |
---|
| 605 | * @return Remote state synchronize object. |
---|
| 606 | */ |
---|
| 607 | RSync* ProjectionModel::getRSync() const |
---|
| 608 | { |
---|
| 609 | return m_pRSync; |
---|
| 610 | } |
---|
| 611 | |
---|
| 612 | /** |
---|
| 613 | * Retrieve the exporter object. |
---|
| 614 | * |
---|
| 615 | * @return Exporter object. |
---|
| 616 | */ |
---|
| 617 | Exporter* ProjectionModel::getExporter() const |
---|
| 618 | { |
---|
| 619 | return m_pExporter; |
---|
| 620 | } |
---|
| 621 | |
---|
| 622 | /** |
---|
| 623 | * Retrieve the GUI controler object. |
---|
| 624 | * |
---|
| 625 | * @return GUI controler object. |
---|
| 626 | */ |
---|
| 627 | GUIControler* ProjectionModel::getGUI() const |
---|
| 628 | { |
---|
| 629 | return m_pGUI; |
---|
| 630 | } |
---|
| 631 | |
---|
| 632 | /** |
---|
| 633 | * Loads the plugins |
---|
| 634 | */ |
---|
| 635 | void ProjectionModel::loadPlugins() |
---|
| 636 | { |
---|
| 637 | foreach (QObject *plugin, QPluginLoader::staticInstances()) |
---|
| 638 | { |
---|
| 639 | ProjectorInterface *projector_interface = qobject_cast<ProjectorInterface*>(plugin); |
---|
| 640 | if (projector_interface) |
---|
| 641 | { |
---|
| 642 | projector_interfaces += projector_interface; |
---|
| 643 | } |
---|
| 644 | SceneInterface *scene_interface = qobject_cast<SceneInterface*>(plugin); |
---|
| 645 | if (scene_interface) |
---|
| 646 | { |
---|
| 647 | scene_interfaces += scene_interface; |
---|
| 648 | } |
---|
| 649 | } |
---|
| 650 | |
---|
| 651 | pluginsDir = QDir(qApp->applicationDirPath()); |
---|
| 652 | |
---|
| 653 | // The following ifdef/endif block is from Qt Examples |
---|
| 654 | #if defined(Q_OS_WIN) |
---|
| 655 | // if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release") |
---|
| 656 | // pluginsDir.cdUp(); |
---|
| 657 | #elif defined(Q_OS_MAC) |
---|
| 658 | if (pluginsDir.dirName() == "MacOS") { |
---|
| 659 | pluginsDir.cdUp(); |
---|
| 660 | pluginsDir.cdUp(); |
---|
| 661 | pluginsDir.cdUp(); |
---|
| 662 | } |
---|
| 663 | #endif |
---|
| 664 | if (!pluginsDir.cd("../lib")) return; |
---|
| 665 | |
---|
| 666 | foreach (QString fileName, pluginsDir.entryList(QDir::Files)) { |
---|
| 667 | QPluginLoader loader(pluginsDir.absoluteFilePath(fileName)); |
---|
| 668 | QObject *plugin = loader.instance(); |
---|
| 669 | if (plugin) { |
---|
| 670 | pluginFileNames += fileName; |
---|
| 671 | |
---|
| 672 | ProjectorInterface *projector_interface = qobject_cast<ProjectorInterface*>(plugin); |
---|
| 673 | if (projector_interface) |
---|
| 674 | { |
---|
| 675 | projector_interfaces += projector_interface; |
---|
| 676 | } |
---|
| 677 | SceneInterface *scene_interface = qobject_cast<SceneInterface*>(plugin); |
---|
| 678 | if (scene_interface) |
---|
| 679 | { |
---|
| 680 | scene_interfaces += scene_interface; |
---|
| 681 | } |
---|
| 682 | } |
---|
| 683 | else |
---|
| 684 | { |
---|
| 685 | QString errorString = loader.errorString(); |
---|
| 686 | QString message; |
---|
| 687 | if (errorString=="Unknown error") |
---|
| 688 | { |
---|
| 689 | message = trUtf8("<p><b>%1</b>: Le plugin a été rejeté<br><i><u>Raison invoquée par le loader</u>: %2</i><br>ATTENTION: Cela peut venir d'une configuration en debug du plugin dynamique.<p><b>OK</b> lance quand même l'application,<br><b>Cancel</b> annule le lancement.").arg(fileName).arg(errorString); |
---|
| 690 | } |
---|
| 691 | else |
---|
| 692 | { |
---|
| 693 | message = trUtf8("<p><b>%1</b>: Le plugin a été rejeté<br><i><u>Raison invoquée par le loader</u>: %2</i><p><b>OK</b> lance quand même l'application,<br><b>Cancel</b> annule le lancement.").arg(fileName).arg(errorString); |
---|
| 694 | } |
---|
| 695 | if (QMessageBox::Cancel==QMessageBox::warning(NULL, trUtf8("Attention"), message, QMessageBox::Ok|QMessageBox::Cancel)) |
---|
| 696 | exit(-1); |
---|
| 697 | } |
---|
| 698 | } |
---|
| 699 | } |
---|
| 700 | |
---|
| 701 | /** |
---|
| 702 | * Set a GLWidget for the current render context. |
---|
| 703 | * |
---|
| 704 | * @parma pGLWidget GLWidget of the current render context. |
---|
| 705 | */ |
---|
| 706 | void ProjectionModel::setRenderContext(QGLWidget* pGLWidget) |
---|
| 707 | { |
---|
| 708 | m_pGLWidget = pGLWidget; |
---|
| 709 | m_pPBuffer = NULL; |
---|
| 710 | } |
---|
| 711 | |
---|
| 712 | /** |
---|
| 713 | * Set a P-Buffer for the current render context. |
---|
| 714 | * |
---|
| 715 | * @parma pPBuffer P-Buffer of the current render context. |
---|
| 716 | */ |
---|
| 717 | void ProjectionModel::setRenderContext(QGLPixelBuffer* pPBuffer) |
---|
| 718 | { |
---|
| 719 | m_pGLWidget = NULL; |
---|
| 720 | m_pPBuffer = pPBuffer; |
---|
| 721 | } |
---|
| 722 | |
---|
| 723 | /** |
---|
| 724 | * Activate the current render context. |
---|
| 725 | */ |
---|
| 726 | void ProjectionModel::activateRenderContext() |
---|
| 727 | { |
---|
| 728 | if (m_pGLWidget) |
---|
| 729 | m_pGLWidget->makeCurrent(); |
---|
| 730 | if (m_pPBuffer) |
---|
| 731 | m_pPBuffer->makeCurrent(); |
---|
| 732 | } |
---|