TDE base libraries and programs
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

364 lines
8.1 KiB

  1. /*
  2. * Copyright (C) 2008 Danilo Cesar Lemes de Paula <danilo@mandriva.com>
  3. * Copyright (C) 2008 Gustavo Boiko <boiko@mandriva.com>
  4. * Mandriva Conectiva
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Library General Public
  8. * License version 2 as published by the Free Software Foundation.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Library General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Library General Public License
  16. * along with this library; see the file COPYING.LIB. If not, write to
  17. * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  18. * Boston, MA 02111-1307, USA.
  19. */
  20. #include <tqdom.h>
  21. #include <tqfile.h>
  22. #include <kdebug.h>
  23. #include "KCrossBGRender.h"
  24. #include <tqapplication.h>
  25. #include <kimageeffect.h>
  26. KCrossBGRender::KCrossBGRender(int desk, int screen, bool drawBackgroundPerScreen, TDEConfig *config): KBackgroundRenderer(desk,screen,drawBackgroundPerScreen,config)
  27. {
  28. useCrossEfect = false;
  29. if ( wallpaperList()[0].endsWith("xml",false) ) {
  30. initCrossFade(wallpaperList()[0]);
  31. }
  32. }
  33. void KCrossBGRender::initCrossFade(TQString xmlFile)
  34. {
  35. useCrossEfect = true;
  36. if (xmlFile.isEmpty()){
  37. useCrossEfect = false;
  38. return;
  39. }
  40. secs = 0;
  41. timeList.empty();
  42. // read the XMLfile
  43. TQDomDocument xmldoc = TQDomDocument(xmlFile);
  44. TQFile file( xmlFile );
  45. if ( !file.open( IO_ReadOnly ) ) {
  46. useCrossEfect = false;
  47. return;
  48. }
  49. if ( !xmldoc.setContent( &file ) ) {
  50. useCrossEfect = false;
  51. file.close();
  52. return;
  53. }
  54. file.close();
  55. TQDomElement docElem = xmldoc.documentElement();
  56. TQDomNode n = docElem.firstChild();
  57. while( !n.isNull() ) {
  58. TQDomElement e = n.toElement(); // try to convert the node to an element.
  59. if( !e.isNull() ) {
  60. if (e.tagName() == "starttime") {
  61. createStartTime(e);
  62. } else if (e.tagName() == "transition") {
  63. createTransition(e);
  64. } else if (e.tagName() == "static") {
  65. createStatic(e);
  66. }
  67. }
  68. n = n.nextSibling();
  69. }
  70. // Setting "now" state
  71. setCurrentEvent(true);
  72. pix = getCurrentPixmap();
  73. useCrossEfect = true;
  74. }
  75. KCrossBGRender::~KCrossBGRender(){
  76. }
  77. TQPixmap KCrossBGRender::pixmap() {
  78. fixEnabled();
  79. if (!useCrossEfect){
  80. TQPixmap p = KBackgroundRenderer::pixmap();
  81. kdDebug() << "Inherited " << p.size() << endl;
  82. if (p.width() == 0 && p.height() == 0){
  83. p.convertFromImage(image());
  84. }
  85. return p;
  86. }
  87. return pix;
  88. }
  89. bool KCrossBGRender::needWallpaperChange(){
  90. if (!useCrossEfect) {
  91. return KBackgroundRenderer::needWallpaperChange();
  92. }
  93. bool forceChange = setCurrentEvent(); // If we change the current state
  94. if (forceChange){ // do not matter what hapens
  95. actualPhase = 0; // we need to change background
  96. return true;
  97. }
  98. // Return false if it's not a transition
  99. if (!current.transition) {
  100. return false;
  101. }
  102. double timeLeft, timeTotal;
  103. TQTime now = TQTime::currentTime();
  104. timeLeft = now.secsTo(current.etime);
  105. if (timeLeft < 0) {
  106. timeLeft += 86400; // before midnight
  107. }
  108. timeTotal = current.stime.secsTo(current.etime);
  109. if (timeTotal < 0) {
  110. timeTotal += 86400;
  111. }
  112. double passed = timeTotal - timeLeft;
  113. double timeCell = timeTotal/60; //Time cell size
  114. //kdDebug() << "\ntimeleft:" << timeLeft << " timeTotal:" << timeTotal
  115. // << "\npassed:" << passed << " timeCell:" << timeCell
  116. // << "\nactualPhase: " << actualPhase << endl;
  117. int aux = passed/timeCell;
  118. if(actualPhase != aux){
  119. //kdDebug() << "needWallpaperChange() => returned true" << endl;
  120. actualPhase = passed/timeCell;
  121. return true;
  122. }
  123. //kdDebug() << "needWallpaperChange() => returned false" << endl;
  124. return false;
  125. }
  126. /*
  127. * This method change the enabledEffect flag to TRUE of FALSE, according
  128. * with multiWallpaperMode and FileName (it needs to be a XML)
  129. */
  130. void KCrossBGRender::fixEnabled(){
  131. TQString w = wallpaperList()[0];
  132. useCrossEfect = false;
  133. if(multiWallpaperMode() == Random || multiWallpaperMode() == InOrder){
  134. if ( w != xmlFileName ){
  135. // New XML File
  136. xmlFileName = w;
  137. if (w.endsWith("xml",false)){
  138. initCrossFade(wallpaperList()[0]);
  139. //useCrossEfect = true;
  140. }else{
  141. // Not, it's not a xml file
  142. useCrossEfect = false;
  143. }
  144. }else if (w.endsWith("xml",false)){
  145. //xmlFile doesn't change
  146. //but it's there
  147. useCrossEfect = true;
  148. }else{
  149. // it's not a XML file
  150. useCrossEfect = false;
  151. }
  152. }
  153. }
  154. void KCrossBGRender::changeWallpaper(bool init){
  155. fixEnabled();
  156. if (!useCrossEfect){
  157. KBackgroundRenderer::changeWallpaper(init);
  158. return;
  159. }
  160. pix = getCurrentPixmap();
  161. }
  162. bool KCrossBGRender::setCurrentEvent(bool init){
  163. TQTime now = TQTime::currentTime();
  164. //Verify if is need to change
  165. if (!(init || now <= current.stime || now >= current.etime )) {
  166. return false;
  167. }
  168. TQValueList<KBGCrossEvent>::iterator it;
  169. for ( it = timeList.begin(); it != timeList.end(); ++it ){
  170. // Look for time
  171. if ( ((*it).stime <= now && now <= (*it).etime) || //normal situation
  172. ((*it).etime <= (*it).stime && (now >= (*it).stime ||
  173. now <= (*it).etime) ) )
  174. {
  175. current = *it;
  176. actualPhase = 0;
  177. //kdDebug() << "Cur: " << current.stime << "< now <" << current.etime << endl;
  178. return true;
  179. }
  180. }
  181. return false;
  182. }
  183. TQPixmap KCrossBGRender::getCurrentPixmap()
  184. {
  185. float alpha;
  186. TQPixmap ret;
  187. TQImage tmp;
  188. TQImage p1;
  189. if (!tmp.load(current.pix1))
  190. return TQPixmap();
  191. // scale the pixmap to fit in the screen
  192. //p1 = TQPixmap(QApplication::desktop()->screenGeometry().size());
  193. //TQPainter p(&p1);
  194. //p.drawPixmap(p1.rect(), tmp);
  195. //
  196. p1 = tmp.smoothScale(TQApplication::desktop()->screenGeometry().size());
  197. if (current.transition){
  198. TQTime now = TQTime::currentTime();
  199. double timeLeft,timeTotal;
  200. TQImage p2;
  201. if (!tmp.load(current.pix2) )
  202. return NULL;
  203. p2 = tmp.smoothScale(TQApplication::desktop()->screenGeometry().size());
  204. //TQPainter p(&p2);
  205. //p.drawPixmap(p2.rect(), tmp);
  206. timeLeft = now.secsTo(current.etime);
  207. if (timeLeft < 0)
  208. timeLeft += 86400;
  209. timeTotal = current.stime.secsTo(current.etime);
  210. if (timeTotal < 0)
  211. timeTotal += 86400;
  212. alpha = (timeTotal - timeLeft)/timeTotal;
  213. //ret = crossFade(p2,p1,alpha);
  214. tmp = KImageEffect::blend(p2,p1,alpha);
  215. ret.convertFromImage(tmp);
  216. return ret;
  217. }else{
  218. ret.convertFromImage(p1);
  219. return ret;
  220. }
  221. }
  222. void KCrossBGRender::createStartTime(TQDomElement docElem)
  223. {
  224. int hour;
  225. int minutes;
  226. TQDomNode n = docElem.firstChild();
  227. while( !n.isNull() ) {
  228. TQDomElement e = n.toElement();
  229. if( !e.isNull() ) {
  230. if (e.tagName() == "hour"){
  231. hour = e.text().toInt();
  232. }else if ( e.tagName() == "minute" ){
  233. minutes = e.text().toInt();
  234. }
  235. }
  236. n = n.nextSibling();
  237. }
  238. secs = hour*60*60 + minutes*60;
  239. }
  240. void KCrossBGRender::createTransition(TQDomElement docElem)
  241. {
  242. int duration;
  243. TQString from;
  244. TQString to;
  245. TQDomNode n = docElem.firstChild();
  246. while( !n.isNull() ) {
  247. TQDomElement e = n.toElement();
  248. if( !e.isNull() ) {
  249. if (e.tagName() == "duration"){
  250. duration = e.text().toFloat();
  251. }else if ( e.tagName() == "from" ){
  252. from = e.text();
  253. }
  254. else if ( e.tagName() == "to" ){
  255. to = e.text();
  256. }
  257. }
  258. n = n.nextSibling();
  259. }
  260. TQTime startTime(0,0,0);
  261. startTime = startTime.addSecs(secs);
  262. TQTime endTime(0,0,0);
  263. endTime = endTime.addSecs(secs+duration);
  264. secs += duration;
  265. KBGCrossEvent l = {true, from, to, startTime,endTime};
  266. timeList.append(l);
  267. }
  268. void KCrossBGRender::createStatic(TQDomElement docElem)
  269. {
  270. int duration;
  271. TQString file;
  272. TQDomNode n = docElem.firstChild();
  273. while( !n.isNull() ) {
  274. TQDomElement e = n.toElement();
  275. if( !e.isNull() ) {
  276. if (e.tagName() == "duration"){
  277. duration = e.text().toFloat();
  278. }else if ( e.tagName() == "file" ){
  279. file = e.text();
  280. }
  281. }
  282. n = n.nextSibling();
  283. }
  284. TQTime startTime(0,0,0);
  285. startTime = startTime.addSecs(secs);
  286. TQTime endTime(0,0,0);
  287. endTime = endTime.addSecs(secs+duration);
  288. secs += duration;
  289. KBGCrossEvent l = {false, file, NULL, startTime,endTime};
  290. timeList.append(l);
  291. }
  292. #include "KCrossBGRender.moc"