1 //===========================================
2 // Lumina Desktop Source Code
3 // Copyright (c) 2016, Ken Moore
4 // Available under the 3-clause BSD license
5 // See the LICENSE file for full details
6 //===========================================
7 #include "page_wallpaper.h"
8 #include "ui_page_wallpaper.h"
9
10 //==========
11 // PUBLIC
12 //==========
page_wallpaper(QWidget * parent)13 page_wallpaper::page_wallpaper(QWidget *parent) : PageWidget(parent), ui(new Ui::page_wallpaper()){
14 ui->setupUi(this);
15 DEFAULTBG = LOS::LuminaShare()+"/desktop-background.jpg";
16 updateIcons();
17 connect(ui->combo_desk_bg, SIGNAL(currentIndexChanged(int)), this, SLOT(deskbgchanged()) );
18 connect(ui->radio_desk_multi, SIGNAL(toggled(bool)), this, SLOT(desktimechanged()) );
19 connect(ui->tool_desk_addbg, SIGNAL(clicked()), this, SLOT(deskbgadded()) );
20 connect(ui->tool_desk_rmbg, SIGNAL(clicked()), this, SLOT(deskbgremoved()) );
21 connect(ui->spin_desk_min, SIGNAL(valueChanged(int)), this, SLOT(desktimechanged()) );
22 connect(ui->combo_desk_layout, SIGNAL(currentIndexChanged(int)), this, SLOT(desktimechanged()) ); //just need to poke the save routines
23 }
24
~page_wallpaper()25 page_wallpaper::~page_wallpaper(){
26
27 }
28
29 //================
30 // PUBLIC SLOTS
31 //================
SaveSettings()32 void page_wallpaper::SaveSettings(){
33 QSettings settings("lumina-desktop","desktopsettings");
34 QString screenID = QApplication::screens().at(cScreen)->name();
35 QString DPrefix = "desktop-"+screenID+"/";
36 QStringList bgs; //get the list of backgrounds to use
37 if(ui->radio_desk_multi->isChecked()){
38 for(int i=0; i<ui->combo_desk_bg->count(); i++){
39 bgs << ui->combo_desk_bg->itemData(i).toString();
40 }
41 }else if(ui->combo_desk_bg->count() > 0){
42 bgs << ui->combo_desk_bg->itemData( ui->combo_desk_bg->currentIndex() ).toString();
43 bgs.removeAll("default");
44 }
45 if(bgs.isEmpty()){ bgs << "default"; } //Make sure to always fall back on the default
46 settings.setValue(DPrefix+"background/filelist", bgs);
47 settings.setValue(DPrefix+"background/minutesToChange", ui->spin_desk_min->value());
48 settings.setValue(DPrefix+"background/format", ui->combo_desk_layout->currentData().toString());
49
50 emit HasPendingChanges(false);
51 }
52
LoadSettings(int screennum)53 void page_wallpaper::LoadSettings(int screennum){
54 emit HasPendingChanges(false);
55 emit ChangePageTitle( tr("Wallpaper Settings") );
56 cScreen = screennum; //save for later
57 loading = true;
58 QSettings settings("lumina-desktop","desktopsettings");
59 QString screenID = QApplication::screens().at(cScreen)->name();
60 QString DPrefix = "desktop-"+screenID+"/";
61
62 QStringList bgs = settings.value(DPrefix+"background/filelist", QStringList()<<"default").toStringList();
63 ui->combo_desk_bg->clear();
64 for(int i=0; i<bgs.length(); i++){
65 if(bgs[i]=="default"){ ui->combo_desk_bg->addItem( QIcon(DEFAULTBG), tr("System Default"), bgs[i] ); }
66 else if(bgs[i].startsWith("rgb(")){ui->combo_desk_bg->addItem(QString(tr("Solid Color: %1")).arg(bgs[i]), bgs[i]); }
67 //else{ ui->combo_desk_bg->addItem( QIcon(QPixmap(bgs[i]).scaled(64,64)), bgs[i].section("/",-1), bgs[i] ); }
68 else{ ui->combo_desk_bg->addItem( bgs[i].section("/",-1), bgs[i] ); } //disable the thumbnail - takes a long time for large collections of files
69 }
70
71 ui->radio_desk_multi->setEnabled(bgs.length()>1);
72 if(bgs.length()>1){ ui->radio_desk_multi->setChecked(true);}
73 else{ ui->radio_desk_single->setChecked(true); }
74 ui->spin_desk_min->setValue( settings.value(DPrefix+"background/minutesToChange", 5).toInt() );
75 desktimechanged(); //ensure the display gets updated (in case the radio selection did not change);
76 QRect geom = QGuiApplication::screens().at(cScreen)->availableGeometry();
77 ui->label_desk_res->setText( tr("Screen Resolution:")+"\n"+QString::number(geom.width())+"x"+QString::number(geom.height()) );
78 int tmp = ui->combo_desk_layout->findData(settings.value(DPrefix+"background/format","stretch"));
79 if(tmp>=0){ ui->combo_desk_layout->setCurrentIndex(tmp); }
80 loading = false;
81 }
82
updateIcons()83 void page_wallpaper::updateIcons(){
84 ui->tool_desk_addbg->setIcon( LXDG::findIcon("list-add","") );
85 ui->tool_desk_rmbg->setIcon( LXDG::findIcon("list-remove","") );
86 updateMenus();
87 }
88
89 //=================
90 // PRIVATE
91 //=================
getColorStyle(QString current,bool allowTransparency)92 QString page_wallpaper::getColorStyle(QString current, bool allowTransparency){
93 QString out;
94 //Convert the current color string into a QColor
95 QStringList col = current.section(")",0,0).section("(",1,1).split(",");
96 if(col.length()!=4){ col.clear(); col << "255" << "255" << "255" << "255"; }
97 QColor ccol = QColor(col[0].toInt(), col[1].toInt(), col[2].toInt(), col[3].toInt()); //RGBA
98 QColor ncol;
99 if(allowTransparency){ ncol= QColorDialog::getColor(ccol, this, tr("Select Color"), QColorDialog::ShowAlphaChannel); }
100 else{ ncol= QColorDialog::getColor(ccol, this, tr("Select Color")); }
101 //Now convert the new color into a usable string and return
102 if(ncol.isValid()){ //if the dialog was not cancelled
103 if(allowTransparency){
104 out = "rgba("+QString::number(ncol.red())+","+QString::number(ncol.green())+","+QString::number(ncol.blue())+","+QString::number(ncol.alpha())+")";
105 }else{
106 out = "rgb("+QString::number(ncol.red())+","+QString::number(ncol.green())+","+QString::number(ncol.blue())+")";
107 }
108 }
109 return out;
110 }
111
112 //=================
113 // PRIVATE SLOTS
114 //=================
updateMenus()115 void page_wallpaper::updateMenus(){
116 //Background file menu (different ways of loading files)
117 if(ui->tool_desk_addbg->menu()==0){ ui->tool_desk_addbg->setMenu(new QMenu(this)); }
118 ui->tool_desk_addbg->menu()->clear();
119 ui->tool_desk_addbg->menu()->addAction(LXDG::findIcon("document-new",""), tr("File(s)"), this, SLOT(deskbgadded()) );
120 ui->tool_desk_addbg->menu()->addAction(LXDG::findIcon("folder-new",""), tr("Directory (Single)"), this, SLOT(deskbgdiradded()) );
121 ui->tool_desk_addbg->menu()->addAction(LXDG::findIcon("document-open-folder",""), tr("Directory (Recursive)"), this, SLOT(deskbgdirradded()) );
122 ui->tool_desk_addbg->menu()->addAction(LXDG::findIcon("format-fill-color",""), tr("Solid Color"), this, SLOT(deskbgcoloradded()) );
123
124 //Available Wallpaper layout options
125 ui->combo_desk_layout->clear();
126 ui->combo_desk_layout->addItem(tr("Automatic"), "stretch");
127 ui->combo_desk_layout->addItem(tr("Fullscreen"), "full");
128 ui->combo_desk_layout->addItem(tr("Fit screen"), "fit");
129 ui->combo_desk_layout->addItem(tr("Tile"), "tile");
130 ui->combo_desk_layout->addItem(tr("Center"), "center");
131 ui->combo_desk_layout->addItem(tr("Top Left"), "topleft");
132 ui->combo_desk_layout->addItem(tr("Top Right"), "topright");
133 ui->combo_desk_layout->addItem(tr("Bottom Left"), "bottomleft");
134 ui->combo_desk_layout->addItem(tr("Bottom Right"), "bottomright");
135
136 }
137
deskbgchanged()138 void page_wallpaper::deskbgchanged(){
139 //Load the new image preview
140 bool allow_time_set = true;
141 if(ui->combo_desk_bg->count()==0){
142 ui->label_desk_bgview->setPixmap(QPixmap());
143 ui->label_desk_bgview->setText(tr("No Background")+"\n"+tr("(use system default)"));
144 ui->label_desk_bgview->setStyleSheet("");
145 allow_time_set = false;
146 }else{
147 allow_time_set = (ui->combo_desk_bg->count()>1);
148 QString path = ui->combo_desk_bg->itemData( ui->combo_desk_bg->currentIndex() ).toString();
149 if(path=="default"){ path = DEFAULTBG; }
150 if(QFileInfo(path).isDir()){
151 allow_time_set = true; //always allow setting the time if a directory is set
152 QDir dir(path);
153 //Got a directory - go ahead and get all the valid image files
154 QStringList imgs = LUtils::imageExtensions();
155 for(int i=0; i<imgs.length(); i++){ imgs[i].prepend("*."); }
156 QStringList files = dir.entryList(imgs, QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
157 //Now update the item/text
158 ui->combo_desk_bg->setItemIcon(ui->combo_desk_bg->currentIndex(), LXDG::findIcon("folder-image","folder"));
159 ui->label_desk_bgview->setPixmap(QPixmap());
160 ui->label_desk_bgview->setText( QString(tr("Image Directory: %1 valid images")).arg(QString::number(files.length()) ));
161 ui->label_desk_bgview->setStyleSheet("");
162 ui->label_desk_bgview->setToolTip(files.join("\n"));
163 }else if(QFile::exists(path)){
164 QSize sz = ui->label_desk_bgview->size();
165 sz.setWidth( sz.width() - (2*ui->label_desk_bgview->frameWidth()) );
166 sz.setHeight( sz.height() - (2*ui->label_desk_bgview->frameWidth()) );
167 //Update the preview/thumbnail for this item
168 QPixmap pix(path);
169 ui->label_desk_bgview->setPixmap( pix.scaled(sz, Qt::KeepAspectRatio, Qt::SmoothTransformation) );
170 ui->combo_desk_bg->setItemIcon(ui->combo_desk_bg->currentIndex(), pix.scaled(64,64) );
171 ui->label_desk_bgview->setStyleSheet("");
172 ui->label_desk_bgview->setToolTip("");
173 }else if(path.startsWith("rgb(")){
174 ui->label_desk_bgview->setPixmap(QPixmap());
175 ui->label_desk_bgview->setText("");
176 ui->label_desk_bgview->setStyleSheet("background-color: "+path+";");
177 ui->label_desk_bgview->setToolTip("");
178 }else{
179 ui->label_desk_bgview->setPixmap(QPixmap());
180 ui->label_desk_bgview->setText(tr("File does not exist"));
181 ui->label_desk_bgview->setStyleSheet("");
182 ui->label_desk_bgview->setToolTip("");
183 }
184 }
185 //See if this constitues a change to the current settings and enable the save button
186 if(!loading && ui->radio_desk_single->isChecked() && cBG!=ui->combo_desk_bg->currentIndex()){ emit HasPendingChanges(true); }
187 cBG = ui->combo_desk_bg->currentIndex(); //keep track of this for later
188 //Disable the background rotation option if only one background selected
189 if(ui->combo_desk_bg->count()<2){
190 ui->radio_desk_single->setChecked(true);
191 ui->radio_desk_multi->setEnabled(false);
192 }else{
193 ui->radio_desk_multi->setEnabled(true);
194 }
195 ui->spin_desk_min->setEnabled(allow_time_set);
196
197 //Disable the bg remove button if no backgrounds loaded
198 ui->tool_desk_rmbg->setEnabled(ui->combo_desk_bg->count()>0);
199 ui->label_desk_bgview->setMinimumSize(10,10);
200 }
201
desktimechanged()202 void page_wallpaper::desktimechanged(){
203 //ui->spin_desk_min->setEnabled(ui->radio_desk_multi->isChecked());
204 if(!loading){ emit HasPendingChanges(true); }
205 }
206
deskbgremoved()207 void page_wallpaper::deskbgremoved(){
208 if(ui->combo_desk_bg->count()<1){ return; } //nothing to remove
209 ui->combo_desk_bg->removeItem( ui->combo_desk_bg->currentIndex() );
210 emit HasPendingChanges(true);
211 }
212
deskbgadded()213 void page_wallpaper::deskbgadded(){
214 //Prompt the user to find an image file to use for a background
215 QString dir = LOS::LuminaShare().section("/lumina-desktop",0,0)+"/wallpapers";
216 qDebug() << "Looking for wallpaper dir:" << dir;
217 if( !QFile::exists(dir) ){ dir = QDir::homePath(); }
218 QStringList imgs = LUtils::imageExtensions();
219 for(int i=0; i<imgs.length(); i++){ imgs[i].prepend("*."); }
220 QStringList bgs = QFileDialog::getOpenFileNames(this, tr("Find Background Image(s)"), dir, "Images ("+imgs.join(" ")+");;All Files (*)");
221 if(bgs.isEmpty()){ return; }
222 for(int i=0; i<bgs.length(); i++){
223 ui->combo_desk_bg->addItem( QIcon(bgs[i]), bgs[i].section("/",-1), bgs[i]);
224 }
225 //Now move to the last item in the list (the new image(s));
226 ui->combo_desk_bg->setCurrentIndex( ui->combo_desk_bg->count()-1 );
227 //If multiple items selected, automatically enable the background rotation option
228 if(bgs.length() > 1 && !ui->radio_desk_multi->isChecked()){
229 ui->radio_desk_multi->setChecked(true);
230 }
231 emit HasPendingChanges(true);
232 }
233
deskbgcoloradded()234 void page_wallpaper::deskbgcoloradded(){
235 //Prompt the user to select a color (no transparency allowed)
236 QString color = getColorStyle("",false); //no initial color
237 if(color.isEmpty()){ return; }
238 //Add it to the list
239 ui->combo_desk_bg->addItem( QString(tr("Solid Color: %1")).arg(color), color);
240 //Now move to the last item in the list (the new image(s));
241 ui->combo_desk_bg->setCurrentIndex( ui->combo_desk_bg->count()-1 );
242
243 emit HasPendingChanges(true);
244 }
245
deskbgdiradded()246 void page_wallpaper::deskbgdiradded(){
247 //Add the files from a single directory
248 QString dir = LOS::LuminaShare().section("/lumina-desktop",0,0)+"/wallpapers";
249 qDebug() << "Looking for wallpaper dir:" << dir;
250 if( !QFile::exists(dir) ){ dir = QDir::homePath(); }
251 dir = QFileDialog::getExistingDirectory(this, tr("Find Background Image Directory"), dir, QFileDialog::ReadOnly);
252 if(dir.isEmpty()){ return; }
253 //Got a directory - go ahead and find all the valid image files within it
254 ui->combo_desk_bg->addItem(dir.section("/",-1), dir);
255 //Now move to the last item in the list (the new image(s));
256 ui->combo_desk_bg->setCurrentIndex( ui->combo_desk_bg->count()-1 );
257 //If multiple items selected, automatically enable the background rotation option
258 /*if(bgs.length() > 1 && !ui->radio_desk_multi->isChecked()){
259 ui->radio_desk_multi->setChecked(true);
260 }*/
261 emit HasPendingChanges(true);
262 }
263
deskbgdirradded()264 void page_wallpaper::deskbgdirradded(){
265 //Recursively add files from a directory
266 QString dir = LOS::LuminaShare().section("/lumina-desktop",0,0)+"/wallpapers";
267 qDebug() << "Looking for wallpaper dir:" << dir;
268 if( !QFile::exists(dir) ){ dir = QDir::homePath(); }
269 dir = QFileDialog::getExistingDirectory(this, tr("Find Background Image Directory"), dir, QFileDialog::ReadOnly);
270 if(dir.isEmpty()){ return; }
271 //Got a directory - go ahead and get all the valid image file formats
272 QStringList imgs = LUtils::imageExtensions();
273 for(int i=0; i<imgs.length(); i++){ imgs[i].prepend("*."); }
274 //Now load the directory and add all the valid files
275 QStringList dirs = LUtils::listSubDirectories(dir, true); //find/list all the dirs
276 dirs.prepend(dir); //make sure the main dir is also listed
277 for(int d=0; d<dirs.length(); d++){
278 ui->combo_desk_bg->addItem(dirs[d].section("/",-1), dirs[d]);
279 }
280 //Now move to the last item in the list (the new image(s));
281 ui->combo_desk_bg->setCurrentIndex( ui->combo_desk_bg->count()-1 );
282 //If multiple items selected, automatically enable the background rotation option
283 if(dirs.length() > 1 && !ui->radio_desk_multi->isChecked()){
284 ui->radio_desk_multi->setChecked(true);
285 }
286 emit HasPendingChanges(true);
287 }
288