diff options
-rw-r--r-- | lumina-desktop/LDesktop.cpp | 302 | ||||
-rw-r--r-- | lumina-desktop/LDesktop.h | 14 | ||||
-rw-r--r-- | lumina-desktop/LDesktopPluginSpace.cpp | 208 | ||||
-rw-r--r-- | lumina-desktop/LDesktopPluginSpace.h | 231 | ||||
-rw-r--r-- | lumina-desktop/desktop-plugins/LDPlugin.cpp | 24 | ||||
-rw-r--r-- | lumina-desktop/desktop-plugins/LDPlugin.h | 83 | ||||
-rw-r--r-- | lumina-desktop/desktop-plugins/LDPluginContainer.h | 152 | ||||
-rw-r--r-- | lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp | 58 | ||||
-rw-r--r-- | lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h | 20 | ||||
-rw-r--r-- | lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp | 3 | ||||
-rw-r--r-- | lumina-desktop/lumina-desktop.pro | 5 |
11 files changed, 604 insertions, 496 deletions
diff --git a/lumina-desktop/LDesktop.cpp b/lumina-desktop/LDesktop.cpp index b9491d72..a1aaac67 100644 --- a/lumina-desktop/LDesktop.cpp +++ b/lumina-desktop/LDesktop.cpp @@ -65,14 +65,7 @@ void LDesktop::prepareToClose(){ //Now close down any desktop plugins desktoplocked = true; //make sure that plugin settings are preserved during removal //Remove all the current containers - QList<QMdiSubWindow*> wins = bgDesktop->subWindowList(); - for(int i=0; i<wins.length(); i++){ - wins[i]->setWhatsThis(""); //clear this so it knows it is being temporarily removed - bgDesktop->removeSubWindow(wins[i]->widget()); //unhook plugin from container - bgDesktop->removeSubWindow(wins[i]); //remove container from screen - delete wins[i]; //delete old container - } - for(int i=0; i<PLUGINS.length(); i++){delete PLUGINS.takeAt(i); i--; } + bgDesktop->cleanup(); } WId LDesktop::backgroundID(){ @@ -120,8 +113,6 @@ void LDesktop::SystemTerminal(){ void LDesktop::SystemFileManager(){ //Just open the home directory QString fm = "lumina-open \""+QDir::homePath()+"\""; - //QString fm = LSession::handle()->sessionSettings()->value("default-filemanager","lumina-fm").toString(); - //if(fm.endsWith(".desktop")){ fm = "lumina-open \""+fm+"\""; } LSession::LaunchApplication(fm); } @@ -196,88 +187,6 @@ void LDesktop::checkResolution(){ issyncing = false; } -LDPluginContainer* LDesktop::CreateDesktopPluginContainer(LDPlugin *plug){ - //Verify that a container does not already exist for this plugin - QList<QMdiSubWindow*> wins = bgDesktop->subWindowList(); - for(int i=0; i<wins.length(); i++){ - if(wins[i]->whatsThis()==plug->ID()){ return 0; } - } - //Create a new plugin container - LDPluginContainer *win = new LDPluginContainer(plug, desktoplocked); - win->loadInitialSize(); //Sizing should be done before adding the window to the area - if(desktoplocked){ - bgDesktop->addSubWindow(win, Qt::Tool | Qt::FramelessWindowHint); - }else{ - bgDesktop->addSubWindow(win, Qt::Tool | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); - } - if( !win->hasFixedPosition() ){ - //NOTE: This section *only* runs for new plugins - it does not run for re-creations of old plugins - //Need to determine the location of the plugin (leave size alone) - if(DEBUG){ qDebug() << " --- Floating Plugin - find a spot for it"; } - QPoint pt = findNewPluginLocation(availDPArea, win->size()); - if(pt.x()>=0 && pt.y()>=0){ - win->saveNewPosition(pt); - win->move(pt); - if(DEBUG){ qDebug() << " --- Moving to point:" << pt; } - } - //Make sure to remove this plugin from the availability region - availDPArea = availDPArea.subtracted( QRegion(win->geometry()) ); - } - QApplication::processEvents(); - QTimer::singleShot(300+(5*PLUGINS.length()), win, SLOT(loadInitialPosition()) ); //Now load the position (if one is saved) - if(DEBUG){ - qDebug() << "Initial DP Geom:" << plug->geometry(); - qDebug() << " - Container Geom:" << win->geometry(); - } - QApplication::processEvents(); - - connect(win, SIGNAL(PluginRemoved(QString)), this, SLOT(DesktopPluginRemoved(QString)) ); - return win; -} - -QPoint LDesktop::findNewPluginLocation(QRegion avail, QSize winsize){ - //This just searches through the region of available space until it find the first location where it - // will fit without overlapping anything else (scanning left->right, top->bottom) - //return QPoint(-1,-1); //just for testing - QRect bounds = avail.boundingRect(); - //qDebug() << "Bounds:" << bounds; - if(bounds.width()<winsize.width() || bounds.height()<winsize.height()){ return QPoint(-1,-1); } - - QPoint pt = bounds.topLeft(); //start in upper-left corner - bool found = false; - if(DEBUG){ qDebug() << "Check Availability:" << bounds << winsize; } - while(pt.y()+winsize.height() < bounds.bottom() && !found){ - int dy = winsize.height()/2; - while(pt.x()+winsize.width() < bounds.right() && !found){ - //Check the horizontal position (incrementing as necessary) - QRegion intersect = avail.intersected(QRect(pt, winsize)); // full intersection - if(DEBUG){ qDebug() << "Check X:" << pt << " - Inter:" << intersect.boundingRect(); } - if(intersect.boundingRect().size()==winsize && intersect.rects().length()==1 ){ found = true; } //use this point - else{ - QRect inter = avail.intersected(QRect(pt, QSize(winsize.width(),1))).boundingRect(); //1D intersection in X-dir - int dx = winsize.width() - inter.width(); - if(dx>0 && inter.left() > pt.x()){ pt.setX( inter.left() ); } - else if(inter.width()==0){ pt.setX( pt.x()+winsize.width() ); } - else{ pt.setX( pt.x()+inter.width() ); } - //Also adjust the dy value to the smallest amount - inter = avail.intersected(QRect(pt, QSize(1,winsize.height()))).boundingRect(); //1D intersection in X-dir - int ddy = inter.y()-pt.y(); - if(ddy < dy && ddy>0){ dy = ddy; } - } - - } - if(!found){ - //Nothing in the horizontal direction - increment the vertical dimension - pt.setX( bounds.left() ); //reset back to the left-most edge - pt.setY( pt.y()+dy ); - if(DEBUG){ qDebug() << "Check Y:" << pt << dy; } - } - } - //qDebug() << "Found Point:" << found << pt; - if(!found){ return QPoint(-1,-1); } //no space found - return an invalid point - else{ return pt; } -} - // ===================== // PRIVATE SLOTS // ===================== @@ -314,10 +223,9 @@ void LDesktop::InitDesktop(){ bgWindow->setGeometry(LSession::handle()->screenGeom(desktopnumber)); connect(bgWindow, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(ShowMenu(const QPoint&)) ); if(DEBUG){ qDebug() << "Create bgDesktop"; } - bgDesktop = new QMdiArea(bgWindow); - //Make sure the desktop area is transparent to show the background - bgDesktop->setBackground( QBrush(Qt::NoBrush) ); - bgDesktop->setStyleSheet( "QMdiArea{ border: none; background: transparent;}" ); + bgDesktop = new LDesktopPluginSpace(bgWindow); //new QMdiArea(bgWindow); + bgDesktop->SetIconSize(qRound(bgDesktop->height()/14.0)); // (For 1600x900 screens - this comes out to 64 pixel icons) + connect(bgDesktop, SIGNAL(PluginRemovedByUser(QString)), this, SLOT(RemoveDeskPlugin(QString)) ); if(DEBUG){ qDebug() << " - Desktop Init Done:" << desktopnumber; } //Start the update processes QTimer::singleShot(10,this, SLOT(UpdateMenu()) ); @@ -342,8 +250,6 @@ void LDesktop::SettingsChanged(){ void LDesktop::LocaleChanged(){ //Update any elements which require a re-translation UpdateMenu(false); //do the full menu refresh - - } void LDesktop::UpdateMenu(bool fast){ @@ -363,7 +269,7 @@ void LDesktop::UpdateMenu(bool fast){ usewinmenu=false; for(int i=0; i<items.length(); i++){ if(items[i]=="terminal"){ deskMenu->addAction(LXDG::findIcon("utilities-terminal",""), tr("Terminal"), this, SLOT(SystemTerminal()) ); } - else if(items[i]=="filemanager"){ deskMenu->addAction( LXDG::findIcon("Insight-FileManager",""), tr("Browse System"), this, SLOT(SystemFileManager()) ); } + else if(items[i]=="filemanager"){ deskMenu->addAction( LXDG::findIcon("user-home",""), tr("Browse System"), this, SLOT(SystemFileManager()) ); } else if(items[i]=="applications"){ deskMenu->addMenu( LSession::handle()->applicationMenu() ); } else if(items[i]=="line"){ deskMenu->addSeparator(); } else if(items[i]=="settings"){ deskMenu->addMenu( LSession::handle()->settingsMenu() ); } @@ -382,11 +288,6 @@ void LDesktop::UpdateMenu(bool fast){ } //Now add the system quit options deskMenu->addSeparator(); - if(!desktoplocked){ - deskMenu->addAction(LXDG::findIcon("document-encrypt",""),tr("Lock Desktop"), this, SLOT(ToggleDesktopLock()) ); - deskMenu->addAction(LXDG::findIcon("snap-orthogonal",""),tr("Snap Plugins to Grid"), this, SLOT(AlignDesktopPlugins()) ); - }else{ deskMenu->addAction(LXDG::findIcon("document-decrypt",""),tr("Unlock Desktop"), this, SLOT(ToggleDesktopLock()) ); } - deskMenu->addSeparator(); deskMenu->addAction(LXDG::findIcon("system-log-out",""), tr("Log Out"), this, SLOT(SystemLogout()) ); } @@ -433,177 +334,37 @@ void LDesktop::UpdateDesktop(){ QTimer::singleShot(200, this, SLOT(UnlockSettings()) ); } //If generating desktop file launchers, add those in + QStringList filelist; if(settings->value(DPREFIX+"generateDesktopIcons",false).toBool()){ QFileInfoList files = LSession::handle()->DesktopFiles(); for(int i=0; i<files.length(); i++){ - plugins << "applauncher::"+files[i].absoluteFilePath()+"---"+DPREFIX; + filelist << files[i].absoluteFilePath(); } } - //Go through the plugins and remove any existing ones that do not show up on the current list - for(int i=0; i<PLUGINS.length(); i++){ - if(!plugins.contains(PLUGINS[i]->ID())){ - //Remove this plugin (with settings) - is not currently listed - DesktopPluginRemoved(PLUGINS[i]->ID(),true); //flag this as an internal removal - i--; - } - } - //Now get an accounting of all the available/used space (overwriting the private variable) - QSize ssize = LSession::handle()->screenGeom(desktopnumber).size(); - //qDebug() << "Screen Size:" << ssize << desktopnumber; - if(bgDesktop->isVisible() && ( (bgDesktop->size().height() <= ssize.height()) && (bgDesktop->size().width() <= ssize.width()) )){ ssize = bgDesktop->size(); qDebug() << " - Adjusted:" << ssize; } - availDPArea = QRegion(QRect(QPoint(0,0), ssize)); //Note that this is child-geometry space - //Remove all the space currently occupied - //qDebug() << "Available Screen Geom:" << avail.boundingRect(); - QList<QMdiSubWindow*> wins = bgDesktop->subWindowList(); - for(int i=0; i<wins.length(); i++){ - qDebug() << "Subtracting Geom:" << wins[i]->geometry(); - availDPArea = availDPArea.subtracted( QRegion(wins[i]->geometry()) ); - } - //Now add/update plugins - for(int i=0; i<plugins.length(); i++){ - //See if this plugin is already there - LDPlugin *plug = 0; - for(int p=0; p<PLUGINS.length(); p++){ - //qDebug() << " -- Existing Plugin:" << PLUGINS[p]->ID() << p << PLUGINS.length(); - if(PLUGINS[p]->ID()==plugins[i]){ - //qDebug() << " -- Found Plugin"; - plug = PLUGINS[p]; - break; - } - } - if(plug==0){ - //New Plugin - if(DEBUG){qDebug() << " -- New Plugin:" << plugins[i];} - plug = NewDP::createPlugin(plugins[i], bgDesktop); - if(plug != 0){ - connect(plug, SIGNAL(OpenDesktopMenu()), this, SLOT(ShowMenu()) ); - if(DEBUG){ qDebug() << " --- Show Plugin"; } - PLUGINS << plug; - QApplication::processEvents(); //need a moment between plugin/container creation - LDPluginContainer *cont = CreateDesktopPluginContainer(plug); - //Done with this plugin - removed it's area from the available space - if(DEBUG){ qDebug() << " --- Done Creating Plugin Container" << cont->geometry(); } - //avail = avail.subtracted( QRegion(cont->geometry()) ); //remove this space from the available region as well - } - } - QApplication::processEvents(); //need to process events between loading of plugins - } -} - -void LDesktop::ToggleDesktopLock(){ - desktoplocked = !desktoplocked; //flip to other value - //Remove all the current containers - QList<QMdiSubWindow*> wins = bgDesktop->subWindowList(); - for(int i=0; i<wins.length(); i++){ - wins[i]->setWhatsThis(""); //clear this so it knows it is being temporarily removed - bgDesktop->removeSubWindow(wins[i]->widget()); //unhook plugin from container - bgDesktop->removeSubWindow(wins[i]); //remove container from screen - delete wins[i]; //delete old container - } - //Now recreate all the containers on the screen - for(int i=0; i<PLUGINS.length(); i++){ - CreateDesktopPluginContainer(PLUGINS[i]); - } - bgDesktop->update(); //refresh visuals - UpdateMenu(false); -} - -void LDesktop::AlignDesktopPlugins(){ - QList<QMdiSubWindow*> wins = bgDesktop->subWindowList(); - QSize fit = bgDesktop->size(); - //Auto-determine the best grid sizing - // It will try to exactly fit the desktop plugin area, with at least 10-20 grid points - int xgrid, ygrid; - xgrid = ygrid = 32; - //while(fit.width()%xgrid != 0){ xgrid = xgrid-1; } - //while(fit.height()%ygrid != 0){ ygrid = ygrid-1; } - //qDebug() << "Grid:" << xgrid << ygrid << fit.width() << fit.height(); - //Make sure there are at least 10 points. It will not fit the area exactly, but should be very close - //while(xgrid < 10){ xgrid = xgrid*2; } - //while(ygrid < 10){ ygrid = ygrid*2; } - //qDebug() << "Grid (adjusted):" << xgrid << ygrid; - // xgrid = int(fit.width()/xgrid); //now get the exact pixel size of the grid - //ygrid = int(fit.height()/ygrid); //now get the exact pixel size of the grid - //qDebug() << "Grid (pixel):" << xgrid << ygrid; - //qDebug() << " X-Grid:" << xgrid << "("+QString::number(fit.width()/xgrid)+" points)"; - //qDebug() << " Y-Grid:" << ygrid << "("+QString::number(fit.height()/ygrid)+" points)"; - for(int i=0; i<wins.length(); i++){ - //align the plugin on a grid point (that is not right/bottom edge) - QRect geom = wins[i]->geometry(); - int x, y; - if(geom.x()<0){ x=0; } - else{ x = qRound(geom.x()/float(xgrid)) * xgrid; } - if(x>= fit.width()){ x = fit.width()-xgrid; geom.setWidth(xgrid); } - if(geom.y()<0){ y=0; } - else{ y = qRound(geom.y()/float(ygrid)) * ygrid; } - if(y>= fit.height()){ y = fit.height()-ygrid; geom.setHeight(ygrid); } - geom.moveTo(x,y); - //Now adjust the size to also be the appropriate grid multiple - geom.setWidth( qRound(geom.width()/float(xgrid))*xgrid ); - geom.setHeight( qRound(geom.height()/float(ygrid))*ygrid ); - - //Now check for edge spillover and adjust accordingly - int diff = (geom.x()+geom.width()) - bgDesktop->size().width(); - if( diff > 0 ){ geom.moveTo( geom.x() - diff, geom.y() ); } - else if( diff > -11 ){ geom.setWidth( geom.width()-diff ); } - diff = (geom.y()+geom.height()) - bgDesktop->size().height(); - if( diff > 0 ){ geom.moveTo( geom.x(), geom.y() - diff ); } - else if( diff > -11 ){ geom.setHeight( geom.height()-diff ); } - //Now move the plugin - wins[i]->setGeometry(geom); - } + UpdateDesktopPluginArea(); + bgDesktop->LoadItems(plugins, filelist); } -void LDesktop::DesktopPluginRemoved(QString ID, bool internal){ - //NOTE: This function is only run when the plugin is deliberately removed - // The "internal" flag is for whether the plugin was closed by the user (external), or programmatically removed (internal) - //Close down that plugin instance (NOTE: the container might have already closed by the user) - if(DEBUG){ qDebug() << "Desktop Plugin Removed:" << ID; } - //First look for the container (just in case) - QList<QMdiSubWindow*> wins = bgDesktop->subWindowList(); - for(int i=0; i<wins.length(); i++){ - if(wins[i]->whatsThis() == ID){ - if(DEBUG){ qDebug() << " - Removing Plugin Container"; } - //wins[i]->setWhatsThis(""); //clear this so it knows it is being temporarily removed - bgDesktop->removeSubWindow(wins[i]->widget()); //unhook plugin from container - bgDesktop->removeSubWindow(wins[i]); //remove container from screen - if(internal){ delete wins[i]; }//delete old container - break; - } - } - - //qDebug() << "PLUGINS:" << PLUGINS.length() << ID; - for(int i=0; i<PLUGINS.length(); i++){ - if(PLUGINS[i]->ID() == ID){ - //qDebug() << "- found ID"; - if(DEBUG){ qDebug() << " - Deleting Desktop Plugin:" << ID; } - //Special check for auto-generated desktop icons - if(ID.startsWith("applauncher::")){ - qDebug() << "Desktop Icon Removal:" << !internal; - PLUGINS[i]->removeSettings(!internal); //Only remove the file if an external removal on an auto-generated shortcut - }else{ - PLUGINS[i]->removeSettings(true); //Remove any settings associated with this plugin - } - delete PLUGINS.takeAt(i); - break; - } - } - - //Now remove that plugin from the internal list (then let the plugin system remove the actual plugin) - QStringList plugins = settings->value(DPREFIX+"pluginlist",QStringList()).toStringList(); - if(DEBUG){ qDebug() << " - Also removing plugin from future list"; } - if(plugins.removeAll(ID) > 0){ - issyncing = true; - if(DEBUG){ qDebug() << " - Save modified plugins list"; } - settings->setValue(DPREFIX+"pluginlist", plugins); - if(DEBUG){ qDebug() << " - Unlock settings file in 200 ms"; } +void LDesktop::RemoveDeskPlugin(QString ID){ + //This is called after a plugin is manually removed by the user + // just need to ensure that the plugin is also removed from the settings file + QStringList plugs = settings->value(DPREFIX+"pluginlist", QStringList()).toStringList(); + if(plugs.contains(ID)){ + plugs.removeAll(ID); + issyncing=true; //don't let the change cause a refresh + settings->setValue(DPREFIX+"pluginlist", plugs); + settings->sync(); QTimer::singleShot(200, this, SLOT(UnlockSettings()) ); + }else if(ID.startsWith("applauncher::") ){ + //This was a temporary plugin (desktop file?) check for existance/dir and remove it as necessary + QString path = ID.section("---",0,0).section("::",1,50); //full file path + QFileInfo info(path); + if(info.exists() && info.canonicalPath()==QDir::homePath()+"/Desktop"){ + //Need to remove this file/dir as well + if(!info.isSymLink() && info.isDir()){ QProcess::startDetached("rm -r \""+info.absoluteFilePath()+"\""); } + else{ QFile::remove(path); } //just remove the file/symlink directly + } } - /*if(QFile::exists(QDir::homePath()+"/.lumina/desktop-plugins/"+ID+".conf")){ - if(DEBUG){ qDebug() << " - Removing settings file"; } - QFile::remove(QDir::homePath()+"/.lumina/desktop-plugins/"+ID+".conf"); - }*/ - if(DEBUG){ qDebug() << " - Done removing plugin"; } } void LDesktop::UpdatePanels(){ @@ -670,15 +431,12 @@ void LDesktop::UpdateDesktopPluginArea(){ //Now remove the X offset to place it on the current screen (needs widget-coords, not global) globalWorkRect = rec; //save this for later rec.moveTopLeft( QPoint( rec.x()-desktop->screenGeometry(desktopnumber).x() , rec.y() ) ); - //qDebug() << "DPlug Area:" << rec.x() << rec.y() << rec.width() << rec.height(); - if(rec == bgDesktop->geometry()){return; } //nothing changed + //qDebug() << "DPlug Area:" << rec << bgDesktop->geometry() << LSession::handle()->desktop()->availableGeometry(bgDesktop); + if(rec.size().isNull() || rec == bgDesktop->geometry()){return; } //nothing changed bgDesktop->setGeometry( rec ); - bgDesktop->setBackground( QBrush(Qt::NoBrush) ); - bgDesktop->update(); + bgDesktop->UpdateGeom(); //just in case the plugin space itself needs to do anything //Re-paint the panels (just in case a plugin was underneath it and the panel is transparent) for(int i=0; i<PANELS.length(); i++){ PANELS[i]->update(); } - //Also need to re-arrange any desktop plugins to ensure that nothing is out of the screen area - AlignDesktopPlugins(); //Make sure to re-disable any WM control flags LSession::handle()->XCB->SetDisableWMActions(bgWindow->winId()); } diff --git a/lumina-desktop/LDesktop.h b/lumina-desktop/LDesktop.h index e1900f5a..041f4ba5 100644 --- a/lumina-desktop/LDesktop.h +++ b/lumina-desktop/LDesktop.h @@ -28,9 +28,9 @@ #include "LPanel.h" //#include "Globals.h" #include "AppMenu.h" +#include "LDesktopPluginSpace.h" #include "desktop-plugins/LDPlugin.h" -#include "desktop-plugins/LDPluginContainer.h" -#include "desktop-plugins/NewDP.h" +//#include "desktop-plugins/NewDP.h" class LDesktop : public QObject{ Q_OBJECT @@ -66,18 +66,14 @@ private: bool defaultdesktop, desktoplocked, issyncing, usewinmenu, bgupdating; QStringList oldBGL; QList<LPanel*> PANELS; - QMdiArea *bgDesktop; //desktop widget area + LDesktopPluginSpace *bgDesktop; //desktop plugin area QWidget *bgWindow; //full screen background QMenu *deskMenu, *winMenu; - //AppMenu *appmenu; QLabel *workspacelabel; QWidgetAction *wkspaceact; QList<LDPlugin*> PLUGINS; QString CBG; //current background QRect globalWorkRect; - LDPluginContainer* CreateDesktopPluginContainer(LDPlugin*); - - QPoint findNewPluginLocation(QRegion avail, QSize winsize); private slots: void InitDesktop(); @@ -98,9 +94,7 @@ private slots: //Desktop plugin system functions void UpdateDesktop(); - void ToggleDesktopLock(); - void AlignDesktopPlugins(); - void DesktopPluginRemoved(QString ID, bool internal = false); + void RemoveDeskPlugin(QString); void UpdatePanels(); diff --git a/lumina-desktop/LDesktopPluginSpace.cpp b/lumina-desktop/LDesktopPluginSpace.cpp new file mode 100644 index 00000000..116c4207 --- /dev/null +++ b/lumina-desktop/LDesktopPluginSpace.cpp @@ -0,0 +1,208 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "LDesktopPluginSpace.h" +#include "LSession.h" +#include "desktop-plugins/NewDP.h" + +#include <LuminaXDG.h> +#include <QDesktopWidget> + +#define DEBUG 0 + +// =================== +// PUBLIC +// =================== +LDesktopPluginSpace::LDesktopPluginSpace(QWidget *parent) : QWidget(parent){ + this->setObjectName("LuminaDesktopPluginSpace"); + this->setStyleSheet("QWidget#LuminaDesktopPluginSpace{ border: none; background: transparent; }"); + this->setAcceptDrops(true); + this->setContextMenuPolicy(Qt::NoContextMenu); + this->setMouseTracking(true); + TopToBottom = true; + plugsettings = LSession::handle()->DesktopPluginSettings(); + +} + +LDesktopPluginSpace::~LDesktopPluginSpace(){ + +} + +void LDesktopPluginSpace::LoadItems(QStringList plugs, QStringList files){ + if(DEBUG){ qDebug() << "Loading Desktop Items:" << plugs << files; } + bool changes = false; + if(plugs != plugins){ plugins = plugs; changes = true; } + if(files != deskitems){ deskitems = files; changes = true; } + if(changes){ QTimer::singleShot(0,this, SLOT(reloadPlugins())); } +} + +void LDesktopPluginSpace::SetIconSize(int size){ + if(DEBUG){ qDebug() << "Set Desktop Icon Size:" << size; } + QSize newsize = calculateItemSize(size); + itemSize = newsize; //save this for all the later icons which are generated (grid size) + UpdateGeom(); + //Now re-set the item icon size + QTimer::singleShot(0,this, SLOT(reloadPlugins()) ); +} + +void LDesktopPluginSpace::cleanup(){ + //Perform any final cleanup actions here + for(int i=0; i<ITEMS.length(); i++){ + delete ITEMS.takeAt(i); + i--; + } + plugins.clear(); + deskitems.clear(); +} +// =================== +// PUBLIC SLOTS +// =================== +void LDesktopPluginSpace::UpdateGeom(){ + if(DEBUG){ qDebug() << "Update Desktop Geom:"; } + //Currently no special checks - might need to add validation of all current plugin geometries in the future +} + +// =================== +// PRIVATE +// =================== +QSize LDesktopPluginSpace::calculateItemSize(int icosize){ + //Note: This returns the size in numbers of cells (width = columnspan, height = rowspan) + QSize sz; + sz.setWidth(1.8*icosize); + sz.setWidth( RoundUp(sz.width()/GRIDSIZE)); //always round up to cell numbers + sz.setHeight(icosize+ 2.3*this->fontMetrics().height() ); + sz.setHeight( RoundUp(sz.height()/GRIDSIZE)); //always round up to cell number + return sz; +} + +void LDesktopPluginSpace::addDesktopItem(QString filepath){ + addDesktopPlugin("applauncher::"+filepath+"---dlink"+QString::number(LSession::handle()->desktop()->screenNumber(this)) ); +} + +void LDesktopPluginSpace::addDesktopPlugin(QString plugID){ + //This is used for generic plugins (QWidget-based) + if(DEBUG){ qDebug() << "Adding Desktop Plugin:" << plugID; } + LDPlugin *plug = NewDP::createPlugin(plugID, this); + plug->setWhatsThis(plugID); + //Now get the geometry for the plugin + QRect geom = plug->loadPluginGeometry(); //in grid coords + if(geom.isNull()){ + //No previous location - need to calculate initial geom + QSize sz = plug->sizeHint(); + if(plugID.startsWith("applauncher::") ){ sz = itemSize*GRIDSIZE; } + geom.setWidth( RoundUp(sz.width()/GRIDSIZE) ); + geom.setHeight( RoundUp(sz.height()/GRIDSIZE) ); + geom.moveTo( findOpenSpot(geom.width(), geom.height()) ); + }else if(!ValidGeometry(plugID, gridToGeom(geom)) ){ + //Find a new location for the plugin (saved location is invalid) + QPoint pt = findOpenSpot(geom.width(), geom.height(), geom.y()-2, geom.x()-2); //try to get it within the same general area + geom.moveTo(pt); + } + if(geom.x() < 0 || geom.y() < 0){ + qDebug() << "No available space for desktop plugin:" << plugID << " - IGNORING"; + delete plug; + }else{ + if(DEBUG){ qDebug() << " - New Plugin Geometry (grid):" << geom; } + //Now place the item in the proper spot/size + plug->setGeometry( gridToGeom(geom) ); + plug->show(); + if(DEBUG){ qDebug() << " - New Plugin Geometry (px):" << plug->geometry(); } + ITEMS << plug; + connect(plug, SIGNAL(StartMoving(QString)), this, SLOT(StartItemMove(QString)) ); + connect(plug, SIGNAL(StartResizing(QString)), this, SLOT(StartItemResize(QString)) ); + connect(plug, SIGNAL(RemovePlugin(QString)), this, SLOT(RemoveItem(QString)) ); + } +} + +QPoint LDesktopPluginSpace::findOpenSpot(int gridwidth, int gridheight, int startRow, int startCol){ + //Note about the return QPoint: x() is the column number, y() is the row number + QPoint pt(0,0); + int row = startRow; int col = startCol; + if(row<0){ row = 0; } //just in case - since this can be recursively called + if(col<0){ col = 0; } //just in case - since this can be recursively called + bool found = false; + int rowCount, colCount; + rowCount = RoundUp(this->height()/GRIDSIZE); + colCount = RoundUp(this->width()/GRIDSIZE); + QRect geom(0, 0, gridwidth*GRIDSIZE, gridheight*GRIDSIZE); //origin point will be adjusted in a moment + if(DEBUG){ qDebug() << "Search for plugin space:" << rowCount << colCount << gridheight << gridwidth << this->size(); } + if(TopToBottom){ + //Arrange Top->Bottom + while(col<(colCount-gridwidth) && !found){ + while(row<(rowCount-gridheight) && !found){ + bool ok = true; + geom.moveTo(col*GRIDSIZE, row*GRIDSIZE); + //qDebug() << " - Check Geom:" << geom << col << row; + //Check all the existing items to ensure no overlap + for(int i=0; i<ITEMS.length() && ok; i++){ + if(geom.intersects(ITEMS[i]->geometry())){ + //Collision - move the next searchable row/column index + ok = false; + row = posToGrid(ITEMS[i]->geometry().bottomLeft()).y(); //use bottom edge for next search + } + } + if(ok){ pt = QPoint(col,row); found = true; } //found an open spot + row++; + } + if(!found){ col++; row=0; } //go to the next column + } + }else{ + //Arrange Left->Right + while(row<(rowCount-gridheight) && !found){ + while(col<(colCount-gridwidth) && !found){ + bool ok = true; + geom.moveTo(col*GRIDSIZE, row*GRIDSIZE); + //Check all the existing items to ensure no overlap + for(int i=0; i<ITEMS.length() && ok; i++){ + if(geom.intersects(ITEMS[i]->geometry())){ + //Collision - move the next searchable row/column index + ok = false; + col = posToGrid(ITEMS[i]->geometry().topRight()).x(); // Fill according to row/column + } + } + if(ok){ pt = QPoint(col,row); found = true; } //found an open spot + else{ col++; } + } + if(!found){ row++; col=0;} //go to the next row + } + } + if(!found){ + //Decrease the size of the item by 1x1 grid points and try again + if(gridwidth>2 && gridheight>2){ + pt = findOpenSpot(gridwidth-1, gridheight-1, 0, 0); + }else{ + pt.setX(-1); pt.setY(-1); //invalid + qDebug() << "Could not find an open spot for a desktop plugin:" << gridwidth << gridheight << startRow << startCol; + } + } + return pt; +} + +// =================== +// PRIVATE SLOTS +// =================== +void LDesktopPluginSpace::reloadPlugins(){ + //Remove any plugins as necessary + QStringList plugs = plugins; + QStringList items = deskitems; + for(int i=0; i<ITEMS.length(); i++){ + if(plugs.contains(ITEMS[i]->whatsThis())){ plugs.removeAll(ITEMS[i]->whatsThis()); } + else if(ITEMS[i]->whatsThis().contains("---dlink") && items.contains(ITEMS[i]->whatsThis().section("---",0,0).section("::",1,50)) ){ + //Account for the variation in the Plugin ID for desktop files + items.removeAll(ITEMS[i]->whatsThis().section("---",0,0).section("::",1,50)); + }else{ ITEMS[i]->Cleanup(); delete ITEMS.takeAt(i); i--; } + } + + //Now create any new items + //First load the plugins (almost always have fixed locations) + for(int i=0; i<plugs.length(); i++){ + addDesktopPlugin(plugs[i]); + } + //Now load the desktop shortcuts (fill in the gaps as needed) + for(int i=0; i<items.length(); i++){ + addDesktopItem(items[i]); + } +} diff --git a/lumina-desktop/LDesktopPluginSpace.h b/lumina-desktop/LDesktopPluginSpace.h new file mode 100644 index 00000000..353543d9 --- /dev/null +++ b/lumina-desktop/LDesktopPluginSpace.h @@ -0,0 +1,231 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef _LUMINA_DESKTOP_LDESKTOP_PLUGIN_SPACE_H +#define _LUMINA_DESKTOP_LDESKTOP_PLUGIN_SPACE_H + +#include <QListWidget> +#include <QDropEvent> +#include <QDrag> //includes all the QDrag*Event classes +#include <QUrl> +#include <QMimeData> +#include <QSettings> +#include <QDebug> + +#include "desktop-plugins/LDPlugin.h" + +#define MIMETYPE QString("x-special/lumina-desktop-plugin") +//#define MIMEPOS QString("x-special/lumina-desktop-plugin-pos") +#define GRIDSIZE 16.0 //Need this to be a double/float - usually used for divisions + +class LDesktopPluginSpace : public QWidget{ + Q_OBJECT + +signals: + void PluginRemovedByUser(QString ID); + +public: + LDesktopPluginSpace(QWidget *parent = 0); + ~LDesktopPluginSpace(); + + void LoadItems(QStringList plugs, QStringList files); + //void setShowGrid(bool show); This is already implemented in QTableView (inherited) + void SetIconSize(int size); + void ArrangeTopToBottom(bool ttb); //if false, will arrange left->right + void cleanup(); + +public slots: + void UpdateGeom(); + +private: + QSettings *plugsettings; + QSize itemSize; + QStringList plugins, deskitems; + QList<LDPlugin*> ITEMS; + bool TopToBottom; + + int RoundUp(double num){ + int out = num; //This will truncate the number + if(out < num){ out++; } //need to increase by 1 + return out; + } + + QSize calculateItemSize(int icosize); + void addDesktopItem(QString filepath); //This will convert it into a valid Plugin ID + void addDesktopPlugin(QString plugID); + + + QPoint findOpenSpot(int gridwidth = 1, int gridheight = 1, int startRow = 0, int startCol = 0); + + QPoint posToGrid(QPoint pos){ + //This assumes a point in widget-relative coordinates + pos.setX( RoundUp(pos.x()/GRIDSIZE)); + pos.setY( RoundUp(pos.y()/GRIDSIZE)); + return pos; + } + + QRect geomToGrid(QRect geom){ + return QRect( RoundUp(geom.x()/GRIDSIZE), RoundUp(geom.y()/GRIDSIZE), \ + RoundUp(geom.width()/GRIDSIZE), RoundUp(geom.height()/GRIDSIZE) ); + + } + QRect gridToGeom(QRect grid){ + //This function incorporates the bottom/right edge matchins procedures (for incomplete last grid) + QRect geom(grid.x()*GRIDSIZE, grid.y()*GRIDSIZE, grid.width()*GRIDSIZE, grid.height()*GRIDSIZE); + //Now check the edge conditions (last right/bottom grid points might be smaller than GRIDSIZE) + //qDebug() << "GridToGeom:" << grid << geom; + if(geom.right() > this->geometry().right() && (geom.right() -this->geometry().right())<GRIDSIZE ){ + geom.setRight(this->geometry().right()); //match up with the edge + } + if(geom.bottom() > this->geometry().bottom() && (geom.bottom() -this->geometry().bottom())<GRIDSIZE ){ + geom.setBottom(this->geometry().bottom()); //match up with the edge + } + //qDebug() << " - Adjusted:" << geom; + return geom; + } + + //Internal simplification for setting up a drag event + void setupDrag(QString id, QString type){ + QMimeData *mime = new QMimeData; + mime->setData(MIMETYPE, QString(type+"::::"+id).toLocal8Bit() ); + //If this is a desktop file - also add it to the generic URI list mimetype + if(id.startsWith("applauncher::")){ + QList<QUrl> urilist; + urilist << QUrl::fromLocalFile( id.section("---",0,0).section("::",1,50) ); + mime->setUrls(urilist); + } + //Create the drag structure + QDrag *drag = new QDrag(this); + drag->setMimeData(mime); + drag->exec(Qt::CopyAction); + } + + bool ValidGeometry(QString id, QRect geom){ + //First check that it is within the desktop area completely + // Note that "this->geometry()" is not in the same coordinate space as the geometry inputs + if(!QRect(0,0,this->width(), this->height()).contains(geom)){ return false; } + //Now check that it does not collide with any other items + for(int i=0; i<ITEMS.length(); i++){ + if(ITEMS[i]->whatsThis()==id){ continue; } + else if(geom.intersects(ITEMS[i]->geometry())){ return false; } + } + return true; + } + + LDPlugin* ItemFromID(QString ID){ + for(int i=0; i<ITEMS.length(); i++){ + if(ITEMS[i]->whatsThis()==ID){ return ITEMS[i]; } + } + return 0; + } + +private slots: + void reloadPlugins(); + + void StartItemMove(QString ID){ + setupDrag(ID, "move"); + } + void StartItemResize(QString ID){ + setupDrag(ID, "resize"); + } + void RemoveItem(QString ID){ + for(int i=0; i<ITEMS.length(); i++){ + if(ITEMS[i]->whatsThis()==ID){ + ITEMS[i]->Cleanup(); + delete ITEMS.takeAt(i); + emit PluginRemovedByUser(ID); + return; + } + } + } + +protected: + //Need Drag and Drop functionality (internal movement) + void dragEnterEvent(QDragEnterEvent *ev){ + if(ev->mimeData()->hasFormat(MIMETYPE) ){ + ev->acceptProposedAction(); //allow this to be dropped here + }else if(ev->mimeData()->hasUrls()){ + ev->acceptProposedAction(); //allow this to be dropped here + }else{ + ev->ignore(); + } + } + + void dragMoveEvent(QDragMoveEvent *ev){ + if(ev->mimeData()->hasFormat(MIMETYPE) ){ + //Internal move/resize - Check for validity + QString act = QString( ev->mimeData()->data(MIMETYPE) ); + LDPlugin *item = ItemFromID(act.section("::::",1,50)); + //qDebug() << "Internal Move Event:" << act << ev->pos(); + if(item!=0){ + QRect geom = item->geometry(); + QPoint grid = posToGrid(ev->pos()); + if(act.section("::::",0,0)=="move"){ + QPoint diff = grid - posToGrid(geom.center()); //difference in grid coords + //qDebug() << "Move Event:" << "Diff:" << diff << "Geom:" << geom << grid << ev->pos(); + geom = geomToGrid(geom); //convert to grid coords + geom.moveTo( (geom.topLeft()+diff) ); + geom = gridToGeom(geom); //convert back to px coords with edge matching + //qDebug() << " - Setting Geometry:" << geom; + if(ValidGeometry(act.section("::::",1,50), geom)){ + item->setGeometry(geom); + ev->acceptProposedAction(); + item->savePluginGeometry(geomToGrid(geom)); + }else{ ev->ignore(); } //invalid location + + }else{ + //Resize operation + QPoint diff = grid - posToGrid(geom.center());; //need difference from center (grid) + geom = geomToGrid(geom); //convert to grid coordinates now + if(diff.x()==0 && diff.y()==0){ + ev->acceptProposedAction(); //nothing to do - but keep the drag active + }else{ + if(diff.x()<0){ geom.setLeft( grid.x()); } //expanding to the left + else if(diff.x()>0){ geom.setRight( grid.x()); } //expanding to the right + if(diff.y()<0){ geom.setTop( grid.y()); } //expanding above + else if(diff.y()>0){ geom.setBottom( grid.y()); } //expanding below + //Now convert back to pixel coords (includes edge matching/adjustments) + geom = gridToGeom(geom); + //Check Validity of new geom + if(ValidGeometry(act.section("::::",1,50), geom)){ + item->setGeometry(geom); + ev->acceptProposedAction(); + item->savePluginGeometry(geomToGrid(geom)); + }else{ ev->ignore(); } //invalid location + } + } + } + }else if(ev->mimeData()->hasUrls()){ + ev->acceptProposedAction(); //allow this to be dropped here + }else{ + ev->ignore(); + } + } + + void dropEvent(QDropEvent *ev){ + //QPoint grid = posToGrid(ev->pos()); + if(ev->mimeData()->hasFormat(MIMETYPE)){ + //Desktop Items getting moved around - already performed in the dragMoveEvent + ev->accept(); + }else if(ev->mimeData()->hasUrls()){ + ev->accept(); + //Files getting dropped here + QList<QUrl> urls = ev->mimeData()->urls(); + qDebug() << "Desktop Drop Event:" << urls; + for(int i=0; i<urls.length(); i++){ + //If this file is not in the desktop folder, move/copy it here + // -- TO-DO + + } + }else{ + //Ignore this event + ev->ignore(); + } + } + +}; + +#endif
\ No newline at end of file diff --git a/lumina-desktop/desktop-plugins/LDPlugin.cpp b/lumina-desktop/desktop-plugins/LDPlugin.cpp index 26ed7eff..c6d2e320 100644 --- a/lumina-desktop/desktop-plugins/LDPlugin.cpp +++ b/lumina-desktop/desktop-plugins/LDPlugin.cpp @@ -7,16 +7,36 @@ #include "LDPlugin.h" #include "../LSession.h" +#include <LuminaXDG.h> LDPlugin::LDPlugin(QWidget *parent, QString id) : QFrame(parent){ PLUGID=id; prefix = id.replace("/","_")+"/"; //qDebug() << "ID:" << PLUGID << prefix; settings = LSession::handle()->DesktopPluginSettings(); + //Setup the plugin system control menu + menu = new QMenu(this); + setupMenu(); + //Setup the internal timer for when to start/stop drag events + dragTimer = new QTimer(this); + dragTimer->setSingleShot(true); + dragTimer->setInterval(500); //1/2 second to show the plugin menu + connect(dragTimer, SIGNAL(timeout()), this, SLOT(showPluginMenu())); //Use plugin-specific values for stylesheet control (applauncher, desktopview, etc...) this->setObjectName(id.section("---",0,0).section("::",0,0)); + this->setContextMenuPolicy(Qt::CustomContextMenu); + this->setMouseTracking(false); //only catch mouse movement events if the mouse is clicked/held on the plugin connect(QApplication::instance(), SIGNAL(LocaleChanged()), this, SLOT(LocaleChange()) ); connect(QApplication::instance(), SIGNAL(IconThemeChanged()), this, SLOT(ThemeChange()) ); + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showPluginMenu()) ); +} + +void LDPlugin::setupMenu(){ + menu->clear(); + menu->addAction( LXDG::findIcon("transform-move",""), tr("Start Moving Item"), this, SLOT(slotStartMove()) ); + menu->addAction( LXDG::findIcon("transform-scale",""), tr("Start Resizing Item"), this, SLOT(slotStartResize()) ); + menu->addSeparator(); + menu->addAction( LXDG::findIcon("edit-delete",""), tr("Remove Item"), this, SLOT(slotRemovePlugin()) ); } void LDPlugin::setInitialSize(int width, int height){ @@ -33,10 +53,10 @@ void LDPlugin::setInitialSize(int width, int height){ this->resize( settings->value(prefix+"location/width").toInt(), settings->value(prefix+"location/height").toInt()); } -void LDPlugin::adjustSize(int width, int height){ +/*void LDPlugin::adjustSize(int width, int height){ settings->setValue(prefix+"location/width",width); settings->setValue(prefix+"location/height",height); settings->sync(); this->resize(width,height); emit PluginResized(); -}
\ No newline at end of file +}*/
\ No newline at end of file diff --git a/lumina-desktop/desktop-plugins/LDPlugin.h b/lumina-desktop/desktop-plugins/LDPlugin.h index a77674ee..6c34ab9c 100644 --- a/lumina-desktop/desktop-plugins/LDPlugin.h +++ b/lumina-desktop/desktop-plugins/LDPlugin.h @@ -23,6 +23,9 @@ #include <QSettings> #include <QMoveEvent> #include <QResizeEvent> +#include <QMouseEvent> +#include <QTimer> +#include <QMenu> class LDPlugin : public QFrame{ Q_OBJECT @@ -30,6 +33,10 @@ class LDPlugin : public QFrame{ private: QString PLUGID, prefix; QSettings *settings; + QMenu *menu; + QTimer *dragTimer; + + void setupMenu(); public: LDPlugin(QWidget *parent = 0, QString id="unknown"); @@ -41,7 +48,16 @@ public: } void setInitialSize(int width, int height); - void adjustSize(int width, int height); + //void adjustSize(int width, int height); + + void savePluginGeometry(QRect geom){ + settings->setValue(prefix+"geometry/desktopGridPoints", geom); + settings->sync(); + } + + QRect loadPluginGeometry(){ + return settings->value(prefix+"geometry/desktopGridPoints", QRect()).toRect(); + } void saveSetting(QString var, QVariant val){ //qDebug() << "Saving Setting:" << prefix+var+QString(" = ")+val.toString(); @@ -67,40 +83,63 @@ public: } - /*virtual void scalePlugin(double xscale, double yscale){ - //This can be re-implemented in the subclassed plugin as necessary - // Example: If there are icons in the plugin which should also be re-scaled - - int val = settings->value("location/width",0).toInt(); - if(val>0){ val = qRound(val*xscale); } - settings->setValue("location/width",val); - - val = settings->value("location/height",0).toInt(); - if(val>0){ val = qRound(val*yscale); } - settings->setValue("location/height",val); - - val = settings->value("location/x",0).toInt(); - if(val>0){ val = qRound(val*xscale); } - settings->setValue("location/x",val); - - val = settings->value("location/y",0).toInt(); - if(val>0){ val = qRound(val*yscale); } - settings->setValue("location/y",val); - }*/ - public slots: virtual void LocaleChange(){ //This needs to be re-implemented in the subclassed plugin //This is where all text is set/translated + setupMenu(); } virtual void ThemeChange(){ //This needs to be re-implemented in the subclassed plugin //This is where all the visuals are set if using Theme-dependant icons. + setupMenu(); + } + void showPluginMenu(){ + menu->popup( QCursor::pos() ); } signals: void OpenDesktopMenu(); void PluginResized(); + + //Signals for communication with the desktop layout system (not generally used by hand) + void StartMoving(QString); //ID of plugin + void StartResizing(QString); //ID of plugin + void RemovePlugin(QString); //ID of plugin + +private slots: + void slotStartMove(){ + QCursor::setPos( this->mapToGlobal(QPoint(this->width()/2, this->height()/2)) ); + emit StartMoving(PLUGID); + } + + void slotStartResize(){ + QCursor::setPos( this->mapToGlobal(QPoint(this->width()/2, this->height()/2)) ); + emit StartResizing(PLUGID); + } + + void slotRemovePlugin(){ + removeSettings(true); + emit RemovePlugin(PLUGID); + } + +protected: + void mousePressEvent(QMouseEvent *ev){ + if(!dragTimer->isActive() && ev->buttons().testFlag(Qt::LeftButton) ){ dragTimer->start(); } + QWidget::mousePressEvent(ev); + } + void mouseReleaseEvent(QMouseEvent *ev){ + if(dragTimer->isActive()){ dragTimer->stop(); } + QWidget::mouseReleaseEvent(ev); + } + void mouseMoveEvent(QMouseEvent *ev){ + if(ev->buttons().testFlag(Qt::LeftButton)){ + if(dragTimer->isActive()){ dragTimer->stop(); } + slotStartMove(); + } + QWidget::mouseMoveEvent(ev); + } + }; #endif diff --git a/lumina-desktop/desktop-plugins/LDPluginContainer.h b/lumina-desktop/desktop-plugins/LDPluginContainer.h deleted file mode 100644 index e7388a80..00000000 --- a/lumina-desktop/desktop-plugins/LDPluginContainer.h +++ /dev/null @@ -1,152 +0,0 @@ -//=========================================== -// Lumina-DE source code -// Copyright (c) 2014, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -// This class is the generic container for a desktop plugin that handles -// saving/restoring all the movement and sizing -//=========================================== -#ifndef _LUMINA_DESKTOP_DESKTOP_PLUGIN_CONTAINER_H -#define _LUMINA_DESKTOP_DESKTOP_PLUGIN_CONTAINER_H - -#include <QObject> -#include <QMdiSubWindow> -#include <QApplication> -#include <QSettings> -#include <QMoveEvent> -#include <QResizeEvent> -#include <QCloseEvent> -#include <QString> -#include <QFile> -#include <QIcon> -#include <QTimer> - -#include "LDPlugin.h" - -class LDPluginContainer : public QMdiSubWindow{ - Q_OBJECT - -private: - QTimer *syncTimer; - bool locked, setup; - LDPlugin *PLUG; - -private slots: - void saveGeometry(){ - if(PLUG==0){ return; } - //if(!locked && !setup){ - PLUG->saveSetting("location/x", this->pos().x()); - PLUG->saveSetting("location/y", this->pos().y()); - PLUG->saveSetting("location/width", this->width()-4); - PLUG->saveSetting("location/height", this->height()-4); - //} - } - -public: - LDPluginContainer(LDPlugin *plugin = 0, bool islocked = true) : QMdiSubWindow(){ - locked = islocked; - setup=true; - PLUG = plugin; - syncTimer = new QTimer(this); - syncTimer->setInterval(500); //save settings 1/2 second after it is moved - syncTimer->setSingleShot(true); //no repeats - connect(syncTimer, SIGNAL(timeout()), this, SLOT(saveGeometry()) ); - this->setWhatsThis(plugin->ID()); - this->setContentsMargins(0,0,0,0); - if(!locked){ - //this->setStyleSheet("LDPluginContainer{ border-width: 1px;}"); - this->setWindowTitle( plugin->ID().replace("---"," - ") ); - //this->setWidget( new QWidget() ); - this->setWidget( plugin ); - //this->setWindowIcon(QIcon()); //remove the Qt icon - }else{ - this->setStyleSheet("LDPluginContainer{ background: transparent; border: none;}"); - this->setWidget(plugin); - } - //qDebug() << "New Container:" << PLUG->size() << PLUG->sizeHint(); - connect(PLUG, SIGNAL(PluginResized()), this, SLOT(loadInitialPosition()) ); - } - - ~LDPluginContainer(){ - } - - void saveNewPosition(QPoint pt){ - //generally only used while a plugin is locked and does not have an initial position - // This works around an issue with QMdiArea moving the new container out of alignment - if(PLUG==0){ return; } - PLUG->saveSetting("location/x",pt.x()); - PLUG->saveSetting("location/y", pt.y()); - } - - bool hasFixedPosition(){ - return (PLUG->readSetting("location/x",-12345).toInt() != -12345); - } - -public slots: - void loadInitialSize(){ - if(PLUG==0){ return; } - QSize sz(PLUG->readSetting("location/width",100).toInt(), PLUG->readSetting("location/height",100).toInt()); - this->resize(sz); - } - - void loadInitialPosition(){ - QRect set(PLUG->readSetting("location/x",-12345).toInt(), PLUG->readSetting("location/y",-12345).toInt(), PLUG->readSetting("location/width",PLUG->size().width()).toInt() +4, PLUG->readSetting("location/height",PLUG->size().height()).toInt()+4); - //qDebug() << "Initial Plugin Location:" << set.x() << set.y() << set.width() << set.height(); - if(set.height() < 10){ set.setHeight(10); } //to prevent foot-shooting - if(set.width() < 10){ set.setWidth(10); } //to prevent foot-shooting - if(set.x()!=-12345 && set.y()!=-12345){ - //this->move(set.x(), set.y()); - this->setGeometry(set); - }else{ - qDebug() << " - Found Size:" << set; - this->resize(set.width(), set.height()); - qDebug() << " - Assigning location:" << this->pos(); - saveNewPosition(this->pos()); - } - this->show(); - QApplication::processEvents(); - setup=false; //done with setup - } - - -signals: - void PluginRemoved(QString); - -protected: - void moveEvent(QMoveEvent *event){ - //qDebug() << "Move Event: " << PLUG->ID() << setup; - //Save this location to the settings - if( !setup ){ - if(syncTimer->isActive()){ syncTimer->stop(); } - syncTimer->start(); - //qDebug() << "DP Move:" << event->pos().x() << event->pos().y(); - } - QMdiSubWindow::moveEvent(event); //be sure to pass this event along to the container - } - - void resizeEvent(QResizeEvent *event){ - //Save this size info to the settings - if(!setup){ - //qDebug() << "DP Resize:" << event->size().width() << event->size().height(); - if(syncTimer->isActive()){ syncTimer->stop(); } - syncTimer->start(); - } - QMdiSubWindow::resizeEvent(event); //be sure to pass this event along to the container - } - - void closeEvent(QCloseEvent *event){ - //qDebug() << "Desktop Plugin Close Event:" << this->whatsThis(); - if( !this->whatsThis().isEmpty() && !locked){ - //Plugin removed by the user - delete the settings file - locked = true; //ensure that the save settings routines don't do anything during the close - emit PluginRemoved( this->whatsThis() ); - } - if(syncTimer->isActive()){ syncTimer->stop(); } //prevent save routine from running in a moment - //settings = 0; //ensure we don't touch the settings file after a close event - QMdiSubWindow::closeEvent(event); //continue closing this window - } - -}; - -#endif diff --git a/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp b/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp index ae454511..3acb83fb 100644 --- a/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp +++ b/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp @@ -9,42 +9,46 @@ AppLauncherPlugin::AppLauncherPlugin(QWidget* parent, QString ID) : LDPlugin(par button->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); button->setAutoRaise(true); button->setText("...\n..."); //Need to set something here so that initial sizing works properly - + button->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); lay->addWidget(button, 0, Qt::AlignCenter); connect(button, SIGNAL(clicked()), this, SLOT(buttonClicked()) ); - menu = new QMenu(this); - int icosize = this->readSetting("iconsize",-1).toInt(); + //menu = new QMenu(this); + /*int icosize = this->readSetting("iconsize",-1).toInt(); if(icosize <1){ icosize = LSession::handle()->sessionSettings()->value("DefaultIconSize",64).toInt(); this->saveSetting("iconsize",icosize); - } - button->setIconSize(QSize(icosize,icosize)); - this->setContextMenuPolicy(Qt::CustomContextMenu); - connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(openContextMenu()) ); + }*/ + //int icosize + //button->setIconSize(QSize(icosize,icosize)); + button->setContextMenuPolicy(Qt::NoContextMenu); + //connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(openContextMenu()) ); watcher = new QFileSystemWatcher(this); connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT( loadButton()) ); //Calculate the initial size of the button //qDebug() << "Button Size:" << button->size(); //qDebug() << "Calculated:" << icosize+4 << icosize+8+qRound(2.15*button->fontMetrics().height()); //qDebug() << "Preferred Size:" << button->sizeHint(); - QSize sz(qRound(1.1*icosize), icosize+qRound(2.7*button->fontMetrics().height()) ); - button->setFixedSize(sz); //make sure to adjust the button on first show. - this->setInitialSize(this->sizeHint().width()+2, this->sizeHint().height()+2); //give the container a bit of a buffer + //QSize sz(qRound(1.1*icosize), icosize+qRound(2.7*button->fontMetrics().height()) ); + //button->setFixedSize(sz); //make sure to adjust the button on first show. + this->setInitialSize(120, 100); //give the container a bit of a buffer QTimer::singleShot(100,this, SLOT(loadButton()) ); } void AppLauncherPlugin::Cleanup(){ //This is run only when the plugin was forcibly closed/removed - if(QFile::exists(button->whatsThis()) && button->whatsThis().startsWith(QDir::homePath()+"/Desktop") ){ + /*if(QFile::exists(button->whatsThis()) && button->whatsThis().startsWith(QDir::homePath()+"/Desktop") ){ deleteFile(); - } + }*/ } -void AppLauncherPlugin::loadButton(bool onchange){ +void AppLauncherPlugin::loadButton(){ QString def = this->ID().section("::",1,50).section("---",0,0).simplified(); QString path = this->readSetting("applicationpath",def).toString(); //use the default if necessary //qDebug() << "Default Application Launcher:" << def << path; bool ok = QFile::exists(path); + int icosize = this->width()/1.8; //This is the same calculation as in the LDesktopPluginSpace + button->setFixedSize( this->width()-4, this->height()-4); + button->setIconSize( QSize(icosize,icosize) ); QString txt; if(path.endsWith(".desktop") && ok){ XDGDesktop file = LXDG::loadDesktopFile(path, ok); @@ -82,12 +86,12 @@ void AppLauncherPlugin::loadButton(bool onchange){ } //Now adjust the visible text as necessary based on font/grid sizing button->setToolTip(txt); - int icosize = this->readSetting("iconsize",64).toInt(); - int bwid = qRound(1.1*icosize); - this->setFixedSize(bwid, icosize+qRound(2.5*button->fontMetrics().height()) ); //make sure to adjust the button on first show. - if(onchange){ this->adjustSize( bwid+4, icosize+8+qRound(2.5*button->fontMetrics().height())); } + //int icosize = this->readSetting("iconsize",64).toInt(); + //int bwid = qRound(1.1*icosize); + //this->setFixedSize(bwid, icosize+qRound(2.5*button->fontMetrics().height()) ); //make sure to adjust the button on first show. + //if(onchange){ this->adjustSize( bwid+4, icosize+8+qRound(2.5*button->fontMetrics().height())); } //qDebug() << "Initial Button Text:" << txt << icosize; - if(button->fontMetrics().width(txt) > (bwid-2) ){ + if(button->fontMetrics().width(txt) > (button->width()-2) ){ //int dash = this->fontMetrics().width("-"); //Text too long, try to show it on two lines txt = txt.section(" ",0,2).replace(" ","\n"); //First take care of any natural breaks @@ -96,11 +100,11 @@ void AppLauncherPlugin::loadButton(bool onchange){ QStringList txtL = txt.split("\n"); for(int i=0; i<txtL.length(); i++){ if(i>1){ txtL.removeAt(i); i--; } //Only take the first two lines - else{ txtL[i] = button->fontMetrics().elidedText(txtL[i], Qt::ElideRight, bwid-2); } + else{ txtL[i] = button->fontMetrics().elidedText(txtL[i], Qt::ElideRight, (button->width()-2) ); } } txt = txtL.join("\n"); }else{ - txt = this->fontMetrics().elidedText(txt,Qt::ElideRight, 2*bwid -4); + txt = this->fontMetrics().elidedText(txt,Qt::ElideRight, 2*button->width() -4); //Now split the line in half for the two lines txt.insert( (txt.count()/2), "\n"); } @@ -109,12 +113,12 @@ void AppLauncherPlugin::loadButton(bool onchange){ //qDebug() << " - Setting Button Text:" << txt; button->setText(txt); //Now setup the menu again - menu->clear(); - menu->addAction(LXDG::findIcon("zoom-in",""), tr("Increase Size"), this, SLOT(increaseIconSize())); + //menu->clear(); + /*menu->addAction(LXDG::findIcon("zoom-in",""), tr("Increase Size"), this, SLOT(increaseIconSize())); menu->addAction(LXDG::findIcon("zoom-out",""), tr("Decrease Size"), this, SLOT(decreaseIconSize())); if( !button->whatsThis().isEmpty() && button->whatsThis().startsWith(QDir::homePath()+"/Desktop") ){ menu->addAction(LXDG::findIcon("list-remove",""), tr("Delete File"), this, SLOT(deleteFile()) ); - } + }*/ QTimer::singleShot(100, this, SLOT(update()) ); //Make sure to re-draw the image in a moment } @@ -137,15 +141,15 @@ void AppLauncherPlugin::buttonClicked(){ } -void AppLauncherPlugin::openContextMenu(){ +/*void AppLauncherPlugin::openContextMenu(){ if(button->underMouse()){ menu->popup(QCursor::pos()); }else{ emit OpenDesktopMenu(); } -} +}*/ -void AppLauncherPlugin::increaseIconSize(){ +/*void AppLauncherPlugin::increaseIconSize(){ int icosize = this->readSetting("iconsize",64).toInt(); icosize += 16; button->setIconSize(QSize(icosize,icosize)); @@ -169,4 +173,4 @@ void AppLauncherPlugin::deleteFile(){ }else{ QFile::remove(button->whatsThis()); } -}
\ No newline at end of file +}*/
\ No newline at end of file diff --git a/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h b/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h index 796d8f04..d6e75fec 100644 --- a/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h +++ b/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h @@ -34,20 +34,26 @@ public: private: QToolButton *button; QFileSystemWatcher *watcher; - QMenu *menu; + //QMenu *menu; private slots: - void loadButton(bool onchange = false); + void loadButton(); void buttonClicked(); - void openContextMenu(); + //void openContextMenu(); - void increaseIconSize(); - void decreaseIconSize(); - void deleteFile(); + //void increaseIconSize(); + //void decreaseIconSize(); + //void deleteFile(); public slots: void LocaleChange(){ - loadButton(true); //force reload + loadButton(); //force reload + } + +protected: + void resizeEvent(QResizeEvent *ev){ + LDPlugin::resizeEvent(ev); + QTimer::singleShot(10, this, SLOT(loadButton()) ); } }; #endif diff --git a/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp b/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp index b1300ec8..0b48a049 100644 --- a/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp +++ b/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp @@ -107,7 +107,8 @@ void DesktopViewPlugin::showMenu(const QPoint &pos){ menu->popup(this->mapToGlobal(pos)); }else{ //Pass the context menu request on to the desktop (emit it from the plugin) - emit OpenDesktopMenu(); + this->showPluginMenu(); + //emit OpenDesktopMenu(); } } diff --git a/lumina-desktop/lumina-desktop.pro b/lumina-desktop/lumina-desktop.pro index 35643295..353324b7 100644 --- a/lumina-desktop/lumina-desktop.pro +++ b/lumina-desktop/lumina-desktop.pro @@ -31,7 +31,7 @@ SOURCES += main.cpp \ LXcbEventFilter.cpp \ LSession.cpp \ LDesktop.cpp \ -# LDesktopPluginSpace.cpp \ + LDesktopPluginSpace.cpp \ LPanel.cpp \ LWinInfo.cpp \ AppMenu.cpp \ @@ -71,7 +71,7 @@ HEADERS += Globals.h \ LXcbEventFilter.h \ LSession.h \ LDesktop.h \ -# LDesktopPluginSpace.h \ + LDesktopPluginSpace.h \ LPanel.h \ LWinInfo.h \ AppMenu.h \ @@ -82,7 +82,6 @@ HEADERS += Globals.h \ panel-plugins/NewPP.h \ panel-plugins/LTBWidget.h \ desktop-plugins/LDPlugin.h \ - desktop-plugins/LDPluginContainer.h \ desktop-plugins/NewDP.h \ panel-plugins/userbutton/LUserButton.h \ panel-plugins/userbutton/UserWidget.h \ |