kpilot

notepad-conduit.cc

Go to the documentation of this file.
00001 /* KPilot
00002 **
00003 ** Copyright (C) 2004 by Adriaan de Groot, Joern Ahrens
00004 **
00005 ** The code for NotepadActionThread::unpackNotePad was taken from
00006 ** Angus Ainslies read-notepad.c, which is part of pilot-link.
00007 ** NotepadActionThread::saveImage is also based on read-notepad.c.
00008 **
00009 ** This file is part of the Notepad conduit, a conduit for KPilot that
00010 ** stores the notepad drawings to files.
00011 */
00012 
00013 /*
00014 ** This program is free software; you can redistribute it and/or modify
00015 ** it under the terms of the GNU Lesser General Public License as published by
00016 ** the Free Software Foundation; either version 2.1 of the License, or
00017 ** (at your option) any later version.
00018 **
00019 ** This program is distributed in the hope that it will be useful,
00020 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00022 ** GNU Lesser General Public License for more details.
00023 **
00024 ** You should have received a copy of the GNU Lesser General Public License
00025 ** along with this program in a file called COPYING; if not, write to
00026 ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00027 ** MA 02110-1301, USA.
00028 */
00029 
00030 /*
00031 ** Bug reports and questions can be sent to kde-pim@kde.org
00032 */
00033 
00034 #include "options.h"
00035 #include "pilotUser.h"
00036 #include "pilotSerialDatabase.h"
00037 
00038 #include "notepad-conduit.h"  // The Conduit action
00039 #include "notepadconduit.h"   // The settings class
00040 
00041 #include <pi-notepad.h>
00042 
00043 #include <qthread.h>
00044 #include <qapplication.h>
00045 #include <qvaluelist.h>
00046 #include <qimage.h>
00047 #include <qdir.h>
00048 #include <qcstring.h>
00049 
00050 extern "C"
00051 {
00052 unsigned long version_conduit_notepad = Pilot::PLUGIN_API;
00053 }
00054 
00055 NotepadConduit::NotepadConduit(KPilotLink *d, const char *n,
00056     const QStringList &args) : ConduitAction(d, n, args)
00057 {
00058     FUNCTIONSETUP;
00059     fConduitName=i18n("Notepad");
00060     thread = 0L;
00061 
00062 }
00063 
00064 NotepadConduit::~NotepadConduit()
00065 {
00066     FUNCTIONSETUP;
00067 }
00068 
00069 /* virtual */ bool NotepadConduit::exec()
00070 {
00071     FUNCTIONSETUP;
00072 
00073 #ifdef DEBUG
00074     DEBUGKPILOT << fname << ": In exec() @" << (unsigned long) this << endl;
00075 #endif
00076 
00077     QDir dir(NotepadConduitSettings::outputDirectory());
00078     if(!dir.exists() && !dir.mkdir(dir.path())) {
00079         emit logError(i18n("Unable to open %1").arg(dir.path()));
00080         delayDone();
00081         return false;
00082     }
00083     else {
00084         thread = new NotepadActionThread(this, deviceLink());
00085         thread->start();
00086         // tickle is disabled due to crashs during sync
00087         // -> PADP TX "unexpected package"
00088 //      startTickle();
00089     }
00090 
00091     return true;
00092 }
00093 
00094 bool NotepadConduit::event(QEvent *e)
00095 {
00096     FUNCTIONSETUP;
00097 
00098     if(e->type() == QEvent::User) {
00099 #ifdef DEBUG
00100         DEBUGKPILOT << fname << ": Notepad thread done." << endl;
00101 #endif
00102 //      stopTickle();
00103         delayDone();
00104         if(thread->getFailed())
00105             logError(i18n("1 notepad could not be saved", "%n notepads could not be saved", thread->getFailed()));
00106         logMessage(i18n("1 notepad saved", "%n notepads saved", thread->getSaved()));
00107         delete thread;
00108         return true;
00109     }
00110     else
00111         return ConduitAction::event(e);
00112 }
00113 
00114 //-----------------------------------------------------------------------------
00115 // NotepadActionThread
00116 //-----------------------------------------------------------------------------
00117 
00118 NotepadActionThread::NotepadActionThread(QObject *parent, KPilotLink *link) :
00119     fParent(parent), fLink(link), notSaved(0), saved(0)
00120 {
00121     FUNCTIONSETUP;
00122 }
00123 
00124 void NotepadActionThread::run()
00125 {
00126     FUNCTIONSETUP;
00127 
00128     PilotDatabase *db = fLink->database( CSL1("npadDB") );
00129 
00130     int n = db->recordCount();
00131 
00132     if ( n > 0 )
00133     {
00134         QValueList<recordid_t> vl = db->idList();
00135         QValueList<recordid_t>::iterator it;
00136         struct NotePad a;
00137         for ( it = vl.begin(); it != vl.end(); ++it )
00138         {
00139             PilotRecord *pr = db->readRecordById(*it);
00140             if(pr)
00141             {
00142                 unpack_NotePad(&a, (unsigned char*)pr->data(), pr->size());
00143                 saveImage(&a);
00144                 free_NotePad(&a);
00145             }
00146         }
00147     }
00148     KPILOT_DELETE(db);
00149     QApplication::postEvent(fParent, new QEvent(QEvent::User));
00150 }
00151 
00152 static void saveImageFromBITS(QImage &image, struct NotePad *n, unsigned int width)
00153 {
00154     FUNCTIONSETUP;
00155     image.setColor(0, qRgb(0xaa, 0xc1 ,0x91));
00156     image.setColor(1, qRgb(0x30, 0x36, 0x29));
00157 
00158     int x = 0;
00159     int y = 0;
00160     int pos = 0;
00161     for(unsigned int i=0; i<n->body.dataLen/2; ++i)
00162     {
00163         for(int j=0; j<n->data[i].repeat; ++j)
00164         {
00165             for(int k=0; k<8; ++k)
00166             {
00167                 y = pos / width;
00168                 x = pos % width ;
00169 
00170                 image.setPixel( x, y,
00171                     (n->data[i].data & 1<<(7-k)) ? 1 : 0 );
00172                 ++pos;
00173             }
00174         }
00175     }
00176 }
00177 
00178 static void saveImageFromUNCOMPRESSED(QImage &image, struct NotePad *n, unsigned int width)
00179 {
00180     FUNCTIONSETUP;
00181 
00182     image.setColor(0, qRgb(0xaa, 0xc1 ,0x91));
00183     image.setColor(1, qRgb(0x30, 0x36, 0x29));
00184 
00185     unsigned int pos = 0;
00186     unsigned int x,y;
00187 
00188     for (unsigned int i=0; i<n->body.dataLen / 2; ++i)
00189     {
00190         for (unsigned int k=0; k<8; ++k)
00191         {
00192             y = pos / width;
00193             x = pos % width ;
00194 
00195             image.setPixel( x, y,
00196                 (n->data[i].repeat & 1<<(7-k)) ? 1 : 0 );
00197             ++pos;
00198         }
00199 
00200         for (unsigned int k=0; k<8; ++k)
00201         {
00202             y = pos / width;
00203             x = pos % width ;
00204 
00205             image.setPixel( x, y,
00206                 (n->data[i].data & 1<<(7-k)) ? 1 : 0 );
00207             ++pos;
00208         }
00209     }
00210 }
00211 
00212 void NotepadActionThread::saveImage(struct NotePad *n)
00213 {
00214     FUNCTIONSETUP;
00215 
00216     // Width needs adjusting, based on whether it's low res (+8)
00217     // or a hi-res notepad image.
00218     int width = n->body.width + ( n->body.width > 160 ? 16 : 8 );
00219     int height = n->body.height;
00220 
00221 
00222     QImage image(width, height, 8, 2);
00223 
00224     switch (n->body.dataType)
00225     {
00226     case NOTEPAD_DATA_BITS :
00227         saveImageFromBITS( image,n,width );
00228         break;
00229     case NOTEPAD_DATA_UNCOMPRESSED :
00230         saveImageFromUNCOMPRESSED( image,n,width );
00231         break;
00232     case NOTEPAD_DATA_PNG :
00233         image.loadFromData((uchar*)(n->data), n->body.dataLen);
00234         break;
00235     default :
00236         // Unknown data type
00237         WARNINGKPILOT << "Unknown data type: " << n->body.dataType << endl;
00238         return;
00239 
00240         // TODO: Post a warning to the UI
00241     }
00242 
00243     QString filename(n->name);
00244     if(filename.isEmpty())
00245     {
00246         filename.sprintf("%4d-%02d-%02d_%02d-%02d-%02d",
00247             n->changeDate.year,
00248             n->changeDate.month,
00249             n->changeDate.day,
00250             n->changeDate.hour,
00251             n->changeDate.min,
00252             n->changeDate.sec);
00253     }
00254     QString imgname = QString("%1/%2.png").arg(NotepadConduitSettings::outputDirectory()).arg(filename);
00255 
00256 
00257 #ifdef DEBUG
00258     DEBUGKPILOT << fname << ": Notepad " << imgname << endl;
00259 #endif
00260     if(!image.save(imgname, "PNG", -1))
00261         ++notSaved;
00262     else
00263         ++saved;
00264 }
00265