Logo
  • Main Page
  • Related Pages
  • Modules
  • Classes
  • Files

mmsswitcher.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider,             *
00003  *                           Matthias Hardt, Guido Madaus                  *
00004  *                                                                         *
00005  *   Copyright (C) 2007-2008 BerLinux Solutions GbR                        *
00006  *                           Stefan Schwarzer & Guido Madaus               *
00007  *                                                                         *
00008  *   Copyright (C) 2009-2013 BerLinux Solutions GmbH                       *
00009  *                                                                         *
00010  *   Authors:                                                              *
00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
00017  *                                                                         *
00018  *   This library is free software; you can redistribute it and/or         *
00019  *   modify it under the terms of the GNU Lesser General Public            *
00020  *   License version 2.1 as published by the Free Software Foundation.     *
00021  *                                                                         *
00022  *   This library is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00025  *   Lesser General Public License for more details.                       *
00026  *                                                                         *
00027  *   You should have received a copy of the GNU Lesser General Public      *
00028  *   License along with this library; if not, write to the                 *
00029  *   Free Software Foundation, Inc.,                                       *
00030  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
00031  **************************************************************************/
00032 
00033 #include "mmscore/mmsswitcher.h"
00034 
00035 IMMSWindowManager               *MMSSwitcher::windowmanager;
00036 MMSPluginManager                *MMSSwitcher::pluginmanager;
00037 MMSInputManager                 *MMSSwitcher::inputmanager;
00038 vector<MMSInputSubscription*>   MMSSwitcher::subscriptions;
00039 
00040 MMSDialogManager          MMSSwitcher::dm;            /**< dialog manager for whole switcher window                      */
00041 MMSMainWindow*            MMSSwitcher::window;        /**< whole switcher window                                         */
00042 map<int, plugin_data_t *> MMSSwitcher::plugins;       /**< loaded plugins                                                */
00043 int                       MMSSwitcher::curr_plugin;   /**< index to pluginSwitchers which points to the current plugin   */
00044 
00045 MMSSwitcherThread       *MMSSwitcher::switcherThread;//my update thread
00046 
00047 #define SWITCHER_MENUBAR            "switcher_menubar"
00048 #define SWITCHER_MENU               "switcher_menu"
00049 #define SWITCHER_MENU_PLUGINNAME    "switcher_menu_pluginname"
00050 #define SWITCHER_MENU_PLUGINTITLE   "switcher_menu_plugintitle"
00051 #define SWITCHER_MENU_PLUGINICON    "switcher_menu_pluginicon"
00052 
00053 #define SWITCHER_MENUBAR_STATIC     "switcher_menubar_static"
00054 #define SWITCHER_MENU_STATIC        "switcher_menu_static"
00055 
00056 /* public */
00057 MMSSwitcher::MMSSwitcher(MMSPluginData *plugindata) :
00058     osdhandler(NULL),
00059     centralhandler(NULL) {
00060     /* switcher instantiated by plugin */
00061     if(plugindata) {
00062         /* get access to the plugin handler */
00063         this->plugindata = plugindata;
00064         if (this->plugindata->getType()->getName()=="OSD_PLUGIN") {
00065             this->osdhandler = this->pluginmanager->getOSDPluginHandler(this->plugindata->getId());
00066             this->showPreviewThread = new MMSSwitcherThread(this);
00067         }
00068         else if (this->plugindata->getType()->getName()=="CENTRAL_PLUGIN") {
00069             this->centralhandler = this->pluginmanager->getCentralPluginHandler(this->plugindata->getId());
00070             this->showPreviewThread = new MMSSwitcherThread(this);
00071         }
00072 
00073         plugin_data_t *pd = new plugin_data_t;
00074         pd->plugindata = *plugindata;
00075         pd->switcher = this;
00076         plugins.insert(std::make_pair(plugindata->getId(), pd));
00077 
00078         return;
00079     }
00080 
00081     /* switcher start */
00082     DEBUGMSG("MMSSwitcher", "startup");
00083 
00084     this->windowmanager = NULL;
00085     this->pluginmanager = NULL;
00086     this->inputmanager  = NULL;
00087     this->curr_plugin = -1;
00088     this->window      = NULL;
00089 
00090     try {
00091         /* get the active osd and central plugins */
00092         DataSource source = DataSource(config.getConfigDBDBMS(),
00093                                        config.getConfigDBDatabase(),
00094                                        config.getConfigDBAddress(),
00095                                        config.getConfigDBPort(),
00096                                        config.getConfigDBUser(),
00097                                        config.getConfigDBPassword());
00098 
00099         /* load switcher dialog */
00100         this->window = (MMSMainWindow*)dm.loadDialog(config.getData() + "/themes/" + config.getTheme() + "/switcher.xml");
00101         if(!this->window) throw MMSError(0, "Error loading switchers root window");
00102 
00103         /* get access to the menu bar */
00104         this->menuBar = (MMSChildWindow *)this->window->findWindow(SWITCHER_MENUBAR);
00105         if(!this->menuBar) throw MMSError(0, "Error loading switchers menuBar childwindow");
00106         this->menu    = dynamic_cast<MMSMenuWidget*>(this->menuBar->findWidget(SWITCHER_MENU));
00107         if(!this->menu) throw MMSError(0, "Error loading switchers menu");
00108 
00109         /* get access to the static menu bar */
00110         this->menuBar_static = (MMSChildWindow *)this->window->findWindow(SWITCHER_MENUBAR_STATIC);
00111         if (this->menuBar_static)
00112             this->menu_static = dynamic_cast<MMSMenuWidget*>(this->menuBar_static->findWidget(SWITCHER_MENU_STATIC));
00113         else
00114             this->menu_static = NULL;
00115 
00116         /* fill the menu */
00117         MMSPluginService service(&source);
00118         addPluginsToMenu(service.getOSDPlugins());
00119         addPluginsToMenu(service.getCentralPlugins());
00120 
00121         /* show the menu bar */
00122         if (this->menuBar_static) {
00123             this->menuBar_static->show();
00124             this->menuBar_static->waitUntilShown();
00125         }
00126         this->menuBar->show();
00127 
00128         /* connect onBeforeScroll callback of the menu widget */
00129         menu->onBeforeScroll->connect(sigc::mem_fun(this,&MMSSwitcher::onBeforeScroll));
00130 
00131         /* connect onSelectItem callback of the menu widget */
00132         menu->onSelectItem->connect(sigc::mem_fun(this,&MMSSwitcher::onSelectItem));
00133 
00134         /* connect onReturn callback of the menu widget */
00135         menu->onReturn->connect(sigc::mem_fun(this,&MMSSwitcher::onReturn));
00136 
00137         /* create inputs */
00138 //        subscribeKey(MMSKEY_MENU);
00139 //        subscribeKey(MMSKEY_BACKSPACE);
00140 
00141         /* start my update thread */
00142         this->switcherThread = new MMSSwitcherThread(this, NULL, NULL, NULL, NULL);
00143         this->switcherThread->start();
00144 
00145     } catch(MMSError &error) {
00146         DEBUGMSG("Switcher", "Abort due to: " + error.getMessage());
00147         throw error;
00148     }
00149 }
00150 
00151 MMSSwitcher::~MMSSwitcher() {
00152     DEBUGMSG("Switcher", "deletion");
00153     this->plugins.clear();
00154     this->subscriptions.clear();
00155 }
00156 
00157 const void MMSSwitcher::addPluginsToMenu(const vector<MMSPluginData *> &plugins) {
00158     vector<MMSPluginData*>::const_iterator i;
00159     vector<MMSPluginData*>::const_iterator end = plugins.end();
00160     for(i = plugins.begin(); i != end; ++i) {
00161         // new item
00162         MMSWidget *pluginItem = this->menu->newItem();
00163         if (!pluginItem) break;
00164 
00165         // set plugin data to the item
00166         DEBUGMSG("MMSSwitcher", (*i)->getName().c_str());
00167         pluginItem->setBinData((void*)(*i));
00168 
00169         // set values if widgets are defined
00170         setMenuItemValues(pluginItem);
00171 
00172         // new static item
00173         if (this->menu_static) {
00174             pluginItem = this->menu_static->newItem();
00175             if (pluginItem) {
00176                 // set plugin data to the item
00177                 pluginItem->setBinData((void*)(*i));
00178 
00179                 // set values if widgets are defined
00180                 setMenuItemValues(pluginItem);
00181             }
00182         }
00183     }
00184 }
00185 
00186 void MMSSwitcher::setMenuItemValues(MMSWidget *item) {
00187     // get the plugin data
00188     if (!item) return;
00189     MMSPluginData *plugindata = (MMSPluginData *)item->getBinData();
00190 
00191     // set the plugin name
00192     MMSLabelWidget *pluginName = dynamic_cast<MMSLabelWidget*>(item->findWidget(SWITCHER_MENU_PLUGINNAME));
00193     if (pluginName) pluginName->setText(plugindata->getName());
00194 
00195     // set the plugin title
00196     MMSLabelWidget *pluginTitle = dynamic_cast<MMSLabelWidget*>(item->findWidget(SWITCHER_MENU_PLUGINTITLE));
00197     if (pluginTitle) pluginTitle->setText(plugindata->getTitle());
00198 
00199     // set the plugin icon
00200     MMSImageWidget *pluginIcon = dynamic_cast<MMSImageWidget*>(item->findWidget(SWITCHER_MENU_PLUGINICON));
00201     if (pluginIcon) {
00202         string path;
00203         string name;
00204 
00205         name = plugindata->getIcon();
00206         if (!searchingForImage(plugindata->getPath(), name, &path))
00207             if (!path.empty())
00208                 pluginIcon->setImage(path, name);
00209             else
00210                 pluginIcon->setImageName(name);
00211         else
00212             pluginIcon->setImageName("plugin_icon.png");
00213 
00214         name = plugindata->getSelectedIcon();
00215         if (!searchingForImage(plugindata->getPath(), name, &path))
00216             if (!path.empty())
00217                 pluginIcon->setSelImage(path, name);
00218             else
00219                 pluginIcon->setSelImageName(name);
00220         else
00221             pluginIcon->setSelImageName("plugin_icon_s.png");
00222     }
00223 }
00224 
00225 int MMSSwitcher::searchingForImage(string pluginpath, string imagename, string *path) {
00226 
00227     // searching for image
00228     MMSFile *myfile;
00229     int err;
00230 
00231     if (imagename.empty()) {
00232         *path = "";
00233         return 1;
00234     }
00235 
00236     // first: current plugin theme, try with ".taff" extension
00237     *path = pluginpath + "/themes/" + config.getTheme() + "/";
00238     myfile = new MMSFile(*path + imagename + ".taff");
00239     err = myfile->getLastError();
00240     delete myfile;
00241     if (err) {
00242         // try without ".taff" extension
00243         myfile = new MMSFile(*path + imagename);
00244         err = myfile->getLastError();
00245         delete myfile;
00246     }
00247 
00248     if (err) {
00249         // second: plugin default theme, try with ".taff" extension
00250         if (config.getTheme() != DEFAULT_THEME) {
00251             *path = pluginpath + "/themes/" + DEFAULT_THEME + "/";
00252             myfile = new MMSFile(*path + imagename + ".taff");
00253             err = myfile->getLastError();
00254             delete myfile;
00255             if (err) {
00256                 // try without ".taff" extension
00257                 myfile = new MMSFile(*path + imagename);
00258                 err = myfile->getLastError();
00259                 delete myfile;
00260             }
00261         }
00262     }
00263     if (err) {
00264         // third: current theme, try with ".taff" extension
00265         *path = "./themes/" + config.getTheme() + "/";
00266         myfile = new MMSFile(*path + imagename + ".taff");
00267         err = myfile->getLastError();
00268         delete myfile;
00269         if (err) {
00270             // try without ".taff" extension
00271             myfile = new MMSFile(*path + imagename);
00272             err = myfile->getLastError();
00273             delete myfile;
00274         }
00275         if (!err) *path = "";
00276     }
00277     if (err) {
00278         // fourth: default theme, try with ".taff" extension
00279         if (config.getTheme() != DEFAULT_THEME) {
00280             *path = "./themes/";
00281             *path = *path + DEFAULT_THEME + "/";
00282             myfile = new MMSFile(*path + imagename + ".taff");
00283             err = myfile->getLastError();
00284             delete myfile;
00285             if (err) {
00286                 // try without ".taff" extension
00287                 myfile = new MMSFile(*path + imagename);
00288                 err = myfile->getLastError();
00289                 delete myfile;
00290             }
00291             if (!err) *path = "";
00292         }
00293     }
00294 
00295     return err;
00296 }
00297 
00298 
00299 
00300 void MMSSwitcher::setWindowManager(IMMSWindowManager *wm) {
00301     this->windowmanager = wm;
00302 }
00303 
00304 void MMSSwitcher::setPluginManager(MMSPluginManager *pm){
00305     this->pluginmanager = pm;
00306 }
00307 
00308 void MMSSwitcher::setInputManager(MMSInputManager  *im) {
00309     this->inputmanager = im;
00310 }
00311 
00312 void MMSSwitcher::onSubscription(MMSInputSubscription *subscription){
00313     MMSKeySymbol key;
00314 
00315     subscription->getKey(key);
00316 
00317     if (key == MMSKEY_BACKSPACE) {
00318         /* hide all shown popups */
00319         /* hide all main windows only if no popups to be hide */
00320         if(this->windowmanager->hideAllPopupWindows()==false)
00321             if(this->windowmanager->hideAllMainWindows(true)==false) {
00322                 /* hide all windows different from default root */
00323                 MMSWindow *w = this->windowmanager->getBackgroundWindow();
00324                 if(w && !(w->isShown()))
00325                     this->windowmanager->hideAllRootWindows();
00326             }
00327     }
00328     else {
00329         if(this->window->isShown()) {
00330             /* hide all main and popup windows */
00331             this->windowmanager->hideAllPopupWindows();
00332             this->windowmanager->hideAllMainWindows();
00333         }
00334         else {
00335             DEBUGMSG("Switcher", "try to show");
00336             /* show the switcher */
00337             show();
00338         }
00339     }
00340 }
00341 
00342 void MMSSwitcher::subscribeKey(MMSKeySymbol key){
00343     MMSInputSubscription *subscription = new MMSInputSubscription(key);
00344 
00345     this->subscriptions.push_back(subscription);
00346     subscription->callback.connect(sigc::mem_fun(this, &MMSSwitcher::onSubscription));
00347     subscription->registerMe();
00348 }
00349 
00350 
00351 void MMSSwitcher::onBeforeScroll(MMSWidget *widget) {
00352     // no plugin set
00353     this->curr_plugin = -1;
00354 
00355     // tell the switcher thread to invoke show preview
00356     this->switcherThread->invokeShowPreview();
00357 
00358     // hide all previews
00359     for (map<int, plugin_data_t *>::iterator i = this->plugins.begin(); i != this->plugins.end(); i++) {
00360         vector<MMSChildWindow *> *wins = &(i->second->previewWins);
00361         for (unsigned int j = 0; j < wins->size(); j++) {
00362             MMSChildWindow *cw = wins->at(j);
00363             cw->hide();
00364             cw->waitUntilHidden();
00365         }
00366     }
00367 }
00368 
00369 void MMSSwitcher::onSelectItem(MMSWidget *widget) {
00370     if (!widget)
00371         widget = this->menu->getSelectedItem();
00372 
00373     // no menu item given
00374     if (!widget)
00375         return;
00376 
00377     // set the static menu
00378     if (this->menu_static)
00379         this->menu_static->setSelected(menu->getSelected());
00380 
00381     MMSPluginData *data = (MMSPluginData*)widget->getBinData();
00382 
00383     // return if current plugin is selected plugin
00384     if(this->curr_plugin == data->getId())
00385         return;
00386 
00387 
00388     // hide all previews
00389     /*for (map<int, plugin_data_t *>::iterator i = this->plugins.begin(); i != this->plugins.end(); i++) {
00390         vector<MMSChildWindow *> *wins = &(i->second->previewWins);
00391         for (unsigned int j = 0; j < wins->size(); j++) {
00392             MMSChildWindow *cw = wins->at(j);
00393             cw->hide();
00394             cw->waitUntilHidden();
00395         }
00396     }
00397     */
00398 
00399     // set current plugin
00400     this->curr_plugin = data->getId();
00401 
00402     // tell the switcher thread to invoke show preview
00403     this->switcherThread->invokeShowPreview();
00404 }
00405 
00406 void MMSSwitcher::onReturn(MMSWidget *widget) {
00407     try {
00408         // get the selected item
00409         widget = this->menu->getSelectedItem();
00410 
00411         // get access to the plugin data
00412         MMSPluginData *data = (MMSPluginData*)widget->getBinData();
00413 
00414         // invoke show
00415         if(data->getType()->getName() == "OSD_PLUGIN") {
00416             MMSOSDPluginHandler *handler = this->pluginmanager->getOSDPluginHandler(data->getId());
00417             handler->invokeShow(NULL);
00418         }
00419         else if(data->getType()->getName() == "CENTRAL_PLUGIN") {
00420             MMSCentralPluginHandler *handler = this->pluginmanager->getCentralPluginHandler(data->getId());
00421             handler->invokeShow(NULL);
00422         }
00423 
00424     } catch(MMSError &error) {
00425         DEBUGMSG("Switcher", "Abort due to: " + error.getMessage());
00426     }
00427 }
00428 
00429 void MMSSwitcher::show() {
00430     MMSConfigData config;
00431     int firstplugin = atoi(config.getFirstPlugin().c_str());
00432     if(firstplugin > 0) {
00433         this->switchToPluginEx(firstplugin);
00434     } else {
00435         this->window->show();
00436     }
00437 }
00438 
00439 void MMSSwitcher::hide() {
00440     this->window->hide();
00441 }
00442 
00443 MMSChildWindow* MMSSwitcher::loadPreviewDialog(string filename, MMSTheme *theme, int id) {
00444     MMSChildWindow *win;
00445 
00446     win = this->dm.loadChildDialog(filename, theme);
00447 
00448     if(win) {
00449         // save the window pointer
00450         map<int, plugin_data_t *>::iterator i = this->plugins.find(id);
00451         if(i != this->plugins.end())
00452             i->second->previewWins.push_back(win);
00453 
00454         // connect the callbacks, so I can handle show/hide of these windows
00455         win->onBeforeShow->connect(sigc::mem_fun(this,&MMSSwitcher::onBeforeShowPreview));
00456     }
00457 
00458     return win;
00459 }
00460 
00461 bool MMSSwitcher::onBeforeShowPreview(MMSWindow *win) {
00462     // plugin selected?
00463     if (this->curr_plugin < 0)
00464         return false;
00465 
00466     // searching the plugin
00467     map<int, plugin_data_t *>::iterator i = this->plugins.find(this->curr_plugin);
00468     if(i == this->plugins.end())
00469         return false;
00470     vector<MMSChildWindow *> *wins = &(i->second->previewWins);
00471 
00472     // search for the window which will shown
00473     int pW = -1;
00474     for (unsigned int i = 0; i < wins->size(); i++) {
00475         if (win == wins->at(i)) {
00476             /* found */
00477             pW = i;
00478             break;
00479         }
00480     }
00481 
00482     if (pW < 0) {
00483         // window not found, stop the show process
00484         return false;
00485     }
00486 
00487     // hide all previews
00488     for (map<int, plugin_data_t *>::iterator i = this->plugins.begin(); i != this->plugins.end(); i++) {
00489         vector<MMSChildWindow *> *wins = &(i->second->previewWins);
00490         for (unsigned int j = 0; j < wins->size(); j++) {
00491             MMSChildWindow *cw = wins->at(j);
00492             if (cw!=win) {
00493                 cw->hide();
00494                 cw->waitUntilHidden();
00495             }
00496         }
00497     }
00498 
00499     // set current preview window
00500     this->switcherThread->previewShown();
00501 
00502     return true;
00503 }
00504 
00505 MMSChildWindow* MMSSwitcher::loadInfoBarDialog(string filename, MMSTheme *theme) {
00506     return NULL;
00507 }
00508 
00509 void MMSSwitcher::setVolume(unsigned int volume, bool init) {
00510 }
00511 
00512 IMMSSwitcher *MMSSwitcher::newSwitcher(MMSPluginData *plugindata) {
00513     return new MMSSwitcher(plugindata);
00514 }
00515 
00516 bool MMSSwitcher::switchToPluginEx(int toplugin) {
00517     if (toplugin >= 0) {
00518         try {
00519             MMSPluginData *data = &this->plugins[toplugin]->plugindata;
00520             if(!data) {
00521                 DEBUGMSG("Switcher", "Plugin with ID = %d not found", toplugin);
00522                 return false;
00523             }
00524 
00525             if(data->getType()->getName() == "OSD_PLUGIN") {
00526                 MMSOSDPluginHandler *handler = this->pluginmanager->getOSDPluginHandler(data->getId());
00527                 handler->invokeShow(NULL);
00528             }
00529             else if(data->getType()->getName() == "CENTRAL_PLUGIN") {
00530                 MMSCentralPluginHandler *handler = this->pluginmanager->getCentralPluginHandler(data->getId());
00531                 handler->invokeShow(NULL);
00532             }
00533 
00534             return true;
00535         } catch(MMSError &error) {
00536             DEBUGMSG("Switcher", "Abort due to: " + error.getMessage());
00537         }
00538     }
00539 
00540     return false;
00541 }
00542 
00543 bool MMSSwitcher::switchToPlugin() {
00544     return switchToPluginEx(this->plugindata->getId());
00545 }
00546 
00547 bool MMSSwitcher::leavePlugin(bool show_switcher) {
00548     bool b = false;
00549 
00550     if (!this->window->isShown())
00551         b = this->windowmanager->hideAllMainWindows(true);
00552 
00553     if (b==false) {
00554         /* hide all windows different from default root */
00555         MMSWindow *w = this->windowmanager->getBackgroundWindow();
00556         if(w && !w->isShown())
00557             this->windowmanager->hideAllRootWindows();
00558     }
00559 
00560     if (!this->window->isShown())
00561         if (show_switcher)
00562             show();
00563 
00564     return true;
00565 }
00566 
00567 /**
00568  * Generic callback for plugin->switcher communication.
00569  *
00570  * If you implement your own switcher, you can call this
00571  * method in your plugins to let the switcher handle
00572  * whatever you want.
00573  *
00574  * @param   data    application specific data
00575  *
00576  * @return  application specific data
00577  */
00578 void* MMSSwitcher::callback(void *data) {
00579     return NULL;
00580 }
00581 
00582 bool MMSSwitcher::revertToLastPlugin() {
00583     return false;
00584 }
00585 
00586 MMSChildWindow* MMSSwitcher::loadChildWindow(string filename, MMSTheme *theme) {
00587     return this->dm.loadChildDialog(filename, theme);
00588 }
00589 
00590 void MMSSwitcher::refresh()
00591 {
00592     if(window != NULL && window->isShown()) {
00593         window->refresh();
00594     }
00595 }
00596 
00597 
00598 MMSWidget *MMSSwitcher::getMyButton() {
00599     return NULL;
00600 }

Generated by doxygen