22
Apr
0

C++ Picmiz Source (Qt, QImage, Drag’n Drop, Qthread)|C++ Picmiz les sources (Qt, QImage, Drag’n Drop, Qthread)

As you may know I developed a software in Qt to resize multiple images using QImage and QThread (multithreading). This software also use drag and drop and search recursively into the path to find images.

The source are a very good example and a very good tutorial for every one who want to stuffs in Qt.

I use Icon for mac and windows etc. So it is a complete example from A to Z.

But I did it very quickly because my girl friend wanted to tag some picture on her mac (and I am on windows) so the code is sometime not clean and the architecture not efficient! I KNOW!

Let’s start with the .pro file.

Picmiz.pro

All the comments needed are directly in the file :


######################################################################
# Automatically generated by qmake (2.01a) mar. avr. 20 20:17:22 2010
######################################################################

#usual Qt stuff
TEMPLATE = app
TARGET =
DEPENDPATH += . Translations
INCLUDEPATH += .

# Input
HEADERS += PicmizCore.hpp
FORMS += PicmizGui.ui
SOURCES += main.cpp PicmizCore.cpp

#the resources files contains a list of filenames that will be into the executable
#for example, interfaces images, icons etc. are into the .exe or .app
RESOURCES += resources.qrc

#I have created a fr translation file, qmake detected it automatically
TRANSLATIONS += Translations/lang_fr.ts

#for mac
mac{
#I want the program to run on PPC and Inteal
CONFIG+=ppc x86
#I want to use the icon file
ICON = Icons/icon.icns
}
#for windows
win32{
#I want to use this resource file as a icon descriptor
RC_FILE = Icons/winicon.rc
}

As you can see, the main difference between mac and windows is the icon file.
Windows need a resource file with the .ico file name in it. And mac needs a .icns file.
More about that : http://doc.qt.nokia.com/4.0/appicon.html

For Windows icon, create a png file and convert it into a .ico (for example, use http://www.convertico.com/ ). And in the winicon.rc will will find :

IDI_ICON1 ICON DISCARDABLE “myappico.ico”

About the mac icon, create a png (512 x 512) and use Icon Composer to create the right file (Developer/applications/Utilities/Icon Composer).

The resource file contains all images that will be put into the executable :


    Images/ball-48.png
    Images/close48.png
    Images/delete48.png
    Images/doc48.png
    Images/export48.png
    Images/folder48.png
    Images/folderadd48.png
    Images/graphic-tools-icon.png
    Images/help48.png
    Images/image48.png
    Images/leftup48.png
    Images/option48.png.png
    Images/Paint-icon.png
    Images/search48.png
    Images/trash48.png

    Translations/lang_fr.qm

More about resource file here : http://doc.trolltech.com/4.6/resources.html

The main file

Basically, the main does the fallowing steps :

  • asks for a language and if it is French use the translation file. Note that the translation file is embedded into the executable (so its path starts with “:/”)
  • Shows the “Please Donate” message
  • Sets the clean look style
  • Shows the windows and starts the application
#include
#include
#include
#include

#include "PicmizCore.hpp"

////////////////////////////////////////
// Lang
////////////////////////////////////////

void setLang(QApplication& app, const QString& idl){
    qWarning(QString("Lang is %1 (lang_%1)").arg(idl).toLatin1());

    QTranslator* translator = new QTranslator();
    translator->load("lang_" + idl,":/Translations");
    app.installTranslator(translator);
}

void manageLang(QApplication& app){
    QSettings settings("Berenger.eu", "Picmiz");
    int lang = settings.value("lang", -1).toInt();
    if( lang == -1){
        QStringList languages;
        languages << "English" << "Francais";
        lang = languages.indexOf(QInputDialog::getItem(0, "Preference", "Choose your language ?", languages, 0, false));
        if(lang == -1){
            lang = 0;
        }
        settings.setValue("lang", lang);
    }

    switch(lang){
        case 0:
            break;
        case 1:
            setLang(app,"fr");
            break;
    }
}

////////////////////////////////////////
// Donate
////////////////////////////////////////

void donate(){
    QSettings settings("Berenger.eu", "Picmiz");
    bool showDonate = settings.value("donate", true).toBool();
    if( showDonate ){
        QMessageBox msgDonate;
        msgDonate.setText(QApplication::tr("This software is free, but it took me severals days to develep it."
                                            "\nTo let this software free and alive, thanks to donate using paypal : <a href="\&quot;http://berenger.eu/picmiz\&quot;">http://berenger.eu/picmiz</a>"));
        msgDonate.setInformativeText(QApplication::tr("Will you donate?"));
        QPushButton* already = msgDonate.addButton(QApplication::tr("I already have"),QMessageBox::YesRole);
        QPushButton* will = msgDonate.addButton(QApplication::tr("I will, ask me later"),QMessageBox::YesRole);
        QPushButton* donot = msgDonate.addButton(QApplication::tr("I don't want"),QMessageBox::NoRole);

        msgDonate.setDefaultButton(will);
        msgDonate.exec();

        if(msgDonate.clickedButton() == already){
            settings.setValue("donate", false);
        }
        else if(msgDonate.clickedButton() == donot){
            QMessageBox::information(0, QApplication::tr("It is your choice"), QApplication::tr("Free Softwares exist thanks to donation.\n"
                                                                                                "In the futur, if you are using Picmiz a lot, please change your opinion and donate."));
            settings.setValue("donate", false);
        }
    }
}

////////////////////////////////////////
// Main
////////////////////////////////////////

int main(int argc, char *argv[] ){
    qRegisterMetaType("Image_t");
    QApplication app(argc, argv);

    manageLang(app);
    donate();

    app.setStyle(new QCleanlooksStyle );

    PicmizCore core;
    core.show();

    return app.exec();
}

The header

The header defines the classes, their methods and implement small ones.

There are two classes :

  • The thread class

This class does the work : searching into directories, loading images or saving images

  • The ui class

This class controls the graphical interface. It as the slots for the buttons, interact with the user and launch the thread when needed

#ifndef PICMIZCORE_H
#define PICMIZCORE_H

#include
#include

#include "ui_PicmizGui.h"

////////////////////////////////////////
// Data Structure
////////////////////////////////////////

/** This structure defines a properties of picture */
typedef struct Image{
    /** The complete path of image : /a/path/file.png */
    QString completePath;
    /** The name file.png */
    QString name;
    /** The directory used to load this image */
    QString root;
}Image_t;

/** An action asked to the thread */
enum Action{
        LOAD_DIR,
        LOAD_LIST,
        SAVE_PICTURE,
        UNDEFINED,
};

/** Resize type image */
enum Ratio {
    KEEP_RATIO,
    NO_RATIO,
};

/** Resize type */
enum ResizeType{
    POURCENTAGE,
    PIXELS,
};

/** Image format */
enum ImageFormat{
    PNG,
    JPEG100,
    JPEG90,
    JPEG75,
};

////////////////////////////////////////
// Loader
////////////////////////////////////////

/**
 * The threaded engine
 */
class Loader : public QThread{
    Q_OBJECT

signals:
    /** emitted when a picture has to be added in the list */
    void addPicture(const QImage& icon, const Image_t& image);
    /** emitted fo inform the work progress */
    void steps(int currentstep, int totalstep);
    /** emitted to inform the progress label */
    void label(const QString& label);
    /** emitted when the work is finished */
    void isFinished();

private:
    /** Stop */
    bool stop;        //< put to false to stop working
    Action action;    //< Type of action requested

    /** To load */
    QString root;
    void loadDirectory();

    /** To create pictures */
    QList images;
    void loadImages();

    /** To save */
    int width;
    Ratio ratio;
    ResizeType widthType;
    int height;
    ResizeType heightType;
    bool createNew;
    QString ouput;
    bool keepHierarchie;
    bool addExtension;
    QString extenssion;
    ImageFormat format;
    bool useTag;
    QString tagFile;
    bool leftTag;
    bool topTag;

    void saveImages();
    QImage GetResizedImage(const QString& )const;
    QImage PutTag( const QImage& , const QImage&)const;
    QString GetSaveDirectory(const Image_t& image);
    void SaveImage(QImage& , const QString&)const;
    void SetWhiteBackground(QImage& pix) const;

    public :
    /** Constructor */
    Loader(QObject * parent = 0): QThread(parent){
        action = UNDEFINED;
    }

    /** To stop current operation */
    void Stop(){
        stop = true;
    }

    /** Set root path before loading a full directory */
    void Root(const QString & path){
        root = path;
        action = LOAD_DIR;
    }

    /** Set a list of image to load miniatures */
    void Images(const QList& in_images){
        images = in_images;
        action = LOAD_LIST;
    }

    /** Before saving images to hard drive */
    void Properties(const QList& in_images, Ratio in_ratio, int in_width, ResizeType in_widthType, int in_height, ResizeType in_heightType,
                        bool in_createNew, QString in_ouput, bool in_keepHierarchie, bool in_addExtension, QString in_extenssion, ImageFormat in_format,
                        bool in_useTag, QString in_tagFile, bool in_leftTag, bool in_topTag){
        images            = in_images;
        width            = in_width;
        ratio            = in_ratio;
        widthType        = in_widthType;
        height            = in_height;
        heightType        = in_heightType;
        createNew        = in_createNew;
        ouput            = in_ouput;
        keepHierarchie    = in_keepHierarchie;
        addExtension    = in_addExtension;
        extenssion        = in_extenssion;
        format            = in_format;
        useTag            = in_useTag;
        tagFile            = in_tagFile;
        leftTag            = in_leftTag;
        topTag            = in_topTag;

        action = SAVE_PICTURE;
    }

    /** To get small image from a big one */
    QImage getSmallImage(const QImage&) const;

    /** Herited method threaded */
    void run(){
        stop = false;

        switch(action){
            case LOAD_DIR:
                loadDirectory();
                break;
            case LOAD_LIST :
                loadImages();
                break;
            case SAVE_PICTURE :
                saveImages();
                break;
        }

        action = UNDEFINED;
        emit isFinished();
    }

};

////////////////////////////////////////
// Gui Class
////////////////////////////////////////

/** The gui class */
 class PicmizCore : public QMainWindow
 {
     Q_OBJECT

 public:
     /** Constructor, set signals, init variables */
     PicmizCore(QWidget *parent = 0): QMainWindow(parent)
     {
         // load ui
        ui.setupUi(this);

         // set icon size
        ui.imagesView->setIconSize(QSize(IconWidth, IconHeight));

         // need to save false
        needToBeSaved = false;

         // signals/slots
        connect(&loader, SIGNAL(isFinished()),
                this, SLOT(LoaderIsFinished()));
        connect(&loader, SIGNAL(steps(int, int)),
                this, SLOT(ThreadSteps(int, int)));
         connect(&loader, SIGNAL(label(QString)),
                 this, SLOT(ThreadLabel(QString)));
        connect(&loader, SIGNAL(addPicture(QImage, Image_t)),
                this, SLOT(LoaderAddPicture(QImage, Image_t)));

        // init progress dialog
        progress = new QProgressDialog ("Picmiz", QApplication::tr("Cancel"), 0, 0, this);
        progress->setWindowModality(Qt::WindowModal);
         connect(progress, SIGNAL(canceled()),
                 this, SLOT(canceled()));

        // accept drag'n drop
        setAcceptDrops(true);

         // init scene
        ui.miniView->setScene(&miniScene);
        ui.viewMiniTag->setScene(&tagScene);

         // load setting from previous use
         loadSettings();
     }

private:

     /** closing event */
     void closeEvent(QCloseEvent *event);

     /** save a project */
     void saveProject();
     /** load a project */
     void loadProject();

    /** enter drag n drop */
    void dragEnterEvent(QDragEnterEvent *event);
    /** drop event */
    void dropEvent(QDropEvent *event);

    /** save settings */
     void saveSettings();
     /** load settings */
     void loadSettings();

 private slots:
     /** user click on an image in the list */
    void    on_imagesView_itemClicked( QListWidgetItem * item );

     /** user click on delete selection */
    void on_buttonDeleteSelection_clicked(bool);
    /** user click on delete all */
    void on_buttonDeleteAll_clicked(bool);

     /** user click on add files */
    void on_buttonAddFiles_clicked(bool);
    /** user click on add dir */
    void on_buttonAddDirs_clicked(bool);

     /** the loader has finished */
    void LoaderIsFinished();
     /** user ask to cancel current work */
     void canceled();

     /** Load has load an image */
    void LoaderAddPicture(const QImage& icon, const Image_t& image);

     /** Loader has progress */
    void ThreadSteps(int currentstep, int totalstep);
     /** Loader has a new label */
    void ThreadLabel(const QString& label);

     /** user ask to picmiz pictures */
    void on_buttonPicmiz_clicked(bool);
     /** user ask to exit */
    void on_buttonExit_clicked(bool);

     /** user ask to output */
    void on_buttonOutput_clicked(bool);
     /** user ask to tag */
    void on_buttonTag_clicked(bool);

     /** user change radio tag */
    void on_radioUseTag_clicked(bool);
      /** user change radio notag */
    void on_radioNoTag_clicked(bool);
      /** to change state */
    void tagWidget(bool state);

     /** user change radio create */
    void on_radioCreateNew_clicked(bool);
      /** user change radio no create */
    void on_radioReplace_clicked(bool);
      /** to change state */
    void replaceWidget(bool state);

     /** user click to save */
    void on_actionSave_Project_triggered ( bool);
     /** user click to save project as */
    void on_actionSave_Project_As_triggered (bool);
     /** user click to load */
    void on_actionLoad_Project_triggered ( bool);

     /** to change state */
    void on_actionAbout_Picmiz_triggered(bool);

     /** to quit */
     void on_actionQuit_triggered(bool);

 private:
     Ui::PicmizWindow ui;        //< The ui
     bool needToBeSaved;        //< Bool if save is needed
    QList images;        //< images
     QProgressDialog * progress;//< Progress dialog
    Loader loader;                //< Loader
    QGraphicsScene miniScene;    //< Scene for mini images
    QGraphicsScene tagScene;    //< Scene for the tag
     QString projectFile;        //< Current Project file

 public:
     /** The company name */
     static const QString Company;
     /** The soft name */
     static const QString Softname;
     /** Icon width */
     static const double IconWidth;
     /** Icon height */
     static const double IconHeight;

     /** clear a scene */
     static void clearScene(QGraphicsScene * scene){
         QList list = scene->items();
         QList::Iterator it = list.begin();
         for ( ; it != list.end(); ++it )
         {
             if ( *it )
             {
                 scene->removeItem(*it);
                 delete *it;
             }
         }
     }
 };

 #endif

The core

Here are the implementation of the mains methods.

#include "PicmizCore.hpp"

////////////////////////////////////////
// Static
////////////////////////////////////////

const QString PicmizCore::Company = "Berenger.eu";
const QString PicmizCore::Softname = "Picmiz";
const double PicmizCore::IconWidth = 40;
const double PicmizCore::IconHeight = 30;

////////////////////////////////////////
// Loader
////////////////////////////////////////

// Buil a small image
QImage Loader::getSmallImage(const QImage& pix) const{
    QImage original = pix.scaled(PicmizCore::IconWidth,PicmizCore::IconHeight,Qt::KeepAspectRatio,Qt::FastTransformation);

    QImage small(PicmizCore::IconWidth,PicmizCore::IconHeight,QImage::Format_ARGB32_Premultiplied);
    QPainter painter(&small);

    painter.setCompositionMode(QPainter::CompositionMode_Source);
    painter.fillRect(small.rect(), Qt::white);

    // center image
    int offsetx = (PicmizCore::IconWidth - original.width()) / 2;
    int offsety = (PicmizCore::IconHeight - original.height()) / 2;

    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    painter.drawImage(offsetx, offsety, original);

    painter.end();

    return small;
}

// load directory
void Loader::loadDirectory(){
    stop = false;

    QStringList filters;
    filters << "*.png" << "*.jpg" << "*.bpm";

    images.clear();

    QStack dirs;
    dirs.push(root);

    // continue if there are sub directory
    while(dirs.size() && !stop){
        QDir currentDir(dirs.pop());
        emit label(QApplication::tr("Discovering Directories : ") + currentDir.dirName());
        msleep(10);

        QStringList child =  currentDir.entryList(filters);

        QStringList::const_iterator itbegin = child.begin();
        QStringList::const_iterator itend = child.end();
        while(itbegin != itend){
            QFileInfo fileInfo(currentDir.path() + "/" + (*itbegin));

            Image_t image;

            image.name = fileInfo.fileName();
            image.completePath = fileInfo.absoluteFilePath();
            image.root = root;

            images.append(image);

            ++itbegin;

        }

        QStringList childdir =  currentDir.entryList(QDir::NoDotAndDotDot | QDir::Dirs);
        QStringList::const_iterator itbegindir = childdir.begin();
        QStringList::const_iterator itenddir = childdir.end();
        while(itbegindir != itenddir && !stop){
            dirs.push(currentDir.path() + "/" + (*itbegindir));
            ++itbegindir;
        }
    }

    loadImages();

}

// load image from a list
void Loader::loadImages(){
    for(int indexImage = 0 ; indexImage < images.size() && !stop; ++indexImage){         QImage pix(images[indexImage].completePath);         if(!pix.isNull()){             emit addPicture(getSmallImage(pix), images[indexImage]);             emit steps(indexImage, images.size());             emit label(QApplication::tr("Loading Picture : ") + images[indexImage].name);             msleep(10);         }     }     images.clear(); } // Resize picture QImage Loader::GetResizedImage(const QString& path) const{     QImage img(path);     if(!img.isNull()){     int desiredWith = img.width();     int desiredHeight = img.height();     // Resize w & h     if( widthType == POURCENTAGE ){         desiredWith = (desiredWith * 0.01) * width;     }     else{         desiredWith = width;     }         if( heightType == POURCENTAGE ){             desiredHeight = (desiredHeight * 0.01) * height;         }         else{             desiredHeight = height;         }     if(ratio == KEEP_RATIO)         return img.scaled(desiredWith,desiredHeight,Qt::KeepAspectRatio,Qt::SmoothTransformation);     else         return img.scaled(desiredWith,desiredHeight,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);     }     else{         return img;     } } void Loader::SetWhiteBackground(QImage& pix) const{     if(pix.hasAlphaChannel()){     QImage result( pix.size(), QImage::Format_ARGB32_Premultiplied);     QPainter painter(&result);     painter.setCompositionMode(QPainter::CompositionMode_Source);     painter.fillRect(result.rect(), Qt::white);     painter.setCompositionMode(QPainter::CompositionMode_SourceOver);     painter.drawImage(0, 0, pix);     painter.end();     pix = result;     } } // Put a tag QImage Loader::PutTag(const QImage& pix, const QImage& tag) const{     QImage result( pix.size(), QImage::Format_ARGB32_Premultiplied);     QPainter painter(&result);     painter.setCompositionMode(QPainter::CompositionMode_Source);     painter.fillRect(result.rect(), Qt::transparent);     painter.setCompositionMode(QPainter::CompositionMode_SourceOver);     painter.drawImage(0, 0, pix);     int tagwidth = pix.height() > tag.height() ? tag.height() : pix.height();
    int tagheight = pix.height() > tag.height() ? tag.height() : pix.height();
    int xtag = 0;
    int ytag = 0;
    if(!topTag){
        ytag = pix.height() - tagheight;
    }
    if(!leftTag){
        xtag = pix.width() - tagwidth;
    }

    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    painter.drawImage(xtag, ytag, tag);

    painter.end();

    return result;
}

// build the path
QString Loader::GetSaveDirectory(const Image_t& image){
    if(!createNew){
        if(image.name.endsWith("png",Qt::CaseInsensitive)) format = PNG;
        else format = JPEG90;
        return image.completePath.left(image.completePath.lastIndexOf("."));
    }
    else{
        QString realFileName(QFileInfo(image.name).baseName());
        if(addExtension) realFileName.append(extenssion);

        if(!keepHierarchie){
            return ouput + realFileName;
        }
        else{
            QString strDirFile = QFileInfo(image.completePath).absolutePath();
            QString pathToRoot = strDirFile.right(strDirFile.size() - image.root.size() - strDirFile.indexOf(image.root));
            QStringList paths = pathToRoot.split('/');

            QDir dRootOutput(ouput);
            foreach(QString nextPath, paths){
                if(nextPath.size()){
                    if(!dRootOutput.exists(nextPath)){
                        dRootOutput.mkdir(nextPath);
                        qWarning(QString("Created dir : %1").arg(dRootOutput.path()).toLatin1());
                    }
                    if(!dRootOutput.cd(nextPath)){
                        qWarning(QString("Cannot Create dir %1 in %2").arg(nextPath).arg(dRootOutput.path()).toLatin1());
                    }
                }
            }

            return dRootOutput.absolutePath() + "/" + realFileName;

        }
    }

}

// save image
void Loader::SaveImage(QImage& pix, const QString& path) const{
    switch(format){
        case PNG:
            pix.save(path+".png","PNG",100);
            break;
        case JPEG100:
            SetWhiteBackground(pix);
            pix.save(path+".jpg","JPEG",100);
            break;
        case JPEG90:
            SetWhiteBackground(pix);
            pix.save(path+".jpg","JPEG",90);
            break;
        default : //case JPEG75,
            SetWhiteBackground(pix);
            pix.save(path+".jpg","JPEG",75);
            break;
    }
}

// save all images
void Loader::saveImages(){
    QImage tag;
    if(useTag){
        tag.load(tagFile);
        qWarning(QString("Tag is used : %1").arg(tagFile).toLatin1());
    }

    for(int indexImage = 0 ; indexImage < images.size() && !stop; ++indexImage){         emit steps(indexImage, images.size());         emit label(QApplication::tr("Saving Picture : ") + images[indexImage].name);         // Load image Resized         QImage pix(GetResizedImage(images[indexImage].completePath));         if(!pix.isNull()){             // Tag             if(useTag) pix = PutTag(pix, tag);             // Create dir if needed             QString savePath = GetSaveDirectory(images[indexImage]);             // save to hard drive             SaveImage(pix,savePath);             msleep(10);         }         else{             qWarning(QString("Error when load : %1").arg(images[indexImage].completePath).toLatin1());         }     }     images.clear(); } //////////////////////////////////////// // Picmiz //////////////////////////////////////// // close event void PicmizCore::closeEvent(QCloseEvent *event){     if ( (QMessageBox::warning(this, QApplication::tr("Quit"),                                QApplication::tr("You ask to quit this application.\n"                                   "Are you sure???"),                                QMessageBox::Ok | QMessageBox::Cancel,                                QMessageBox::Cancel)) == QMessageBox::Ok) {         event->accept();
        saveSettings();
    } else {
        event->ignore();
    }
}

////////////////////////// Drag/drop //////////////////////////////

// dag enter
void PicmizCore::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasFormat("text/uri-list"))
        event->acceptProposedAction();
}

// drop event
void PicmizCore::dropEvent(QDropEvent *event)
{
    QList urls = event->mimeData()->urls();
    if (urls.isEmpty())
        return;

    QList tmpimages;

    foreach(QUrl urlfile, urls){
        QString file = urlfile.toLocalFile();
        QFileInfo fileInfo(file);

        if(fileInfo.suffix().toLower() == "png" || fileInfo.suffix().toLower() == "jpg"){
            Image_t image;

            image.name = fileInfo.fileName();
            image.completePath = fileInfo.absoluteFilePath();

            tmpimages.append(image);
        }
    }

    progress->reset();
    progress->show();

    loader.Images(tmpimages);
    loader.start();

}

////////////////////////// Buttons //////////////////////////////

// item clicked
 void    PicmizCore::on_imagesView_itemClicked( QListWidgetItem * item ){
    clearScene(&miniScene);

    int index = item->data(Qt::UserRole).toInt();
         QPixmap pix(images[index].completePath);
        QPixmap pixmini(pix.scaled(ui.miniView->width() * 0.95,ui.miniView->height() * 0.95,Qt::KeepAspectRatio,Qt::FastTransformation));
        QGraphicsPixmapItem * picture = miniScene.addPixmap(pixmini);
        picture->setOffset((ui.miniView->width()-pixmini.width())/2,(ui.miniView->height()-pixmini.height())/2);

        ui.labelFilePic->setText(images[index].name); //name
        ui.labelSizePic->setText(QString("%1 / %2").arg(pix.width()).arg(pix.height())); //size
        ui.labelFormatPic->setText(QFileInfo(images[index].name).suffix()); //format
 }

// delete selection
void PicmizCore::on_buttonDeleteSelection_clicked(bool){
    QList selected = ui.imagesView->selectedItems();
    if(selected.size()){
        for(int indexImageSelected = selected.size() - 1 ; indexImageSelected >= 0 ; --indexImageSelected){
            images.removeAt(selected[indexImageSelected]->data(Qt::UserRole).toInt());
            delete(selected[indexImageSelected]);
        }
    }
}

// delete all
void PicmizCore::on_buttonDeleteAll_clicked(bool){
        images.clear();
        ui.imagesView->clear();
}

// add files
void PicmizCore::on_buttonAddFiles_clicked(bool){
    QSettings settings(Company, Softname);
    QString originForImages =  settings.value("originForImages", QDir::home().path()).toString();

    QStringList files = QFileDialog::getOpenFileNames(this ,
                                                          QApplication::tr("Choose Pictures"),
                                                          originForImages ,
                                                          QApplication::tr("Images (*.png *.jpg)"));
    if(files.size()){
        settings.setValue("originForImages", files[0]);
        QList tmpimages;

                    foreach(QString file, files){
                        QFileInfo fileInfo(file);

                        Image_t image;

                        image.name = fileInfo.fileName();
                        image.completePath = fileInfo.absoluteFilePath();

                        tmpimages.append(image);

                    }

        progress->reset();
        progress->show();

        loader.Images(tmpimages);
        loader.start();

    }
}

// add dir
void PicmizCore::on_buttonAddDirs_clicked(bool){
    QSettings settings(Company, Softname);
    QString originForDirs =  settings.value("originForDirs", QDir::home().path()).toString();

    QString dir_name = QFileDialog::getExistingDirectory(this, QApplication::tr("Choose Directory"),
                                                        originForDirs,
                                                        QFileDialog::ShowDirsOnly
                                                        | QFileDialog::DontResolveSymlinks);
    if(!dir_name.isEmpty()){
        settings.setValue("originForDirs", dir_name);

        progress->reset();
        progress->show();

        loader.Root(dir_name);
        loader.start();
    }
}

// cancel
void PicmizCore::canceled(){
    loader.Stop();
}

////////////////////////// Loader event //////////////////////////////

// loader has finished
 void PicmizCore::LoaderIsFinished(){
    progress->close();
     update();
     repaint();
 }

 void PicmizCore::LoaderAddPicture(const QImage& icon, const Image_t& image){
     images.append(image);

     QListWidgetItem *item = new QListWidgetItem(image.name, ui.imagesView);
     item->setIcon(QIcon(QPixmap::fromImage(icon)));
     item->setData(Qt::UserRole, images.size() - 1);
 }

 void PicmizCore::ThreadSteps(int currentstep, int totalstep){
     progress->setValue(currentstep);
     progress->setMaximum(totalstep);
 }
void PicmizCore::ThreadLabel(const QString& label){
    progress->setLabelText(label);
}

////////////////////////// Events //////////////////////////////

void PicmizCore::on_buttonPicmiz_clicked(bool){
    if(ui.radioCreateNew->isChecked() && ui.labelOutput->text().isEmpty()){
        QMessageBox::warning(this,QApplication::tr("Impossible"),
                             QApplication::tr("You have to specify an output directory before\n"
                                                "Click on the output button and select the desired directory."));
        return;
    }

    if(!ui.radioCreateNew->isChecked() && QMessageBox::No == QMessageBox::question(this, QApplication::tr("Be carreful"), QApplication::tr("You ask to replace the origials pictures by the new one,\nAre you sure?"), QMessageBox::Yes | QMessageBox::No)){
        return;
    }

    QString extenssion = ui.lineExtension->text();
    if(extenssion.size()){
        extenssion.replace("$TIME",QDateTime::currentDateTime().toString("hh:mm:ss"));
        extenssion.replace("$DATE",QDate::currentDate().toString("dd.MM.yyyy"));
        extenssion.replace("$RES",QString("%1%2 %3%4").arg(ui.widthValue->value()).arg(ui.comboTypeWidth->currentText()).arg(ui.heightValue->value()).arg(ui.comboTypeHeight->currentText()));
    }

    progress->reset();
    progress->show();

    ImageFormat format;
    switch (ui.comboTypeFormat->currentIndex()) {
        case 0:
            format = PNG;
            break;
        case 1:
            format = JPEG100;
            break;
        case 3:
            format = JPEG75;
            break;
        default:
            format = JPEG90;
            break;
    }

    loader.Properties(images,
                      (ui.checkRatio->isChecked()?KEEP_RATIO:NO_RATIO),ui.widthValue->value(), (ui.comboTypeWidth->currentIndex()?POURCENTAGE:PIXELS),
                      ui.heightValue->value(), (ui.comboTypeHeight->currentIndex()?POURCENTAGE:PIXELS),
                      ui.radioCreateNew->isChecked(), ui.labelOutput->text(), ui.checkHierarchy->isChecked(), ui.checkExtension->isChecked(), extenssion, format,
                      ui.radioUseTag->isChecked(), ui.buttonTag->text(), ui.radioLeft->isChecked(), ui.radioTop->isChecked());
    loader.run();
}

void PicmizCore::on_buttonExit_clicked(bool){
    close();
}

void PicmizCore::on_buttonOutput_clicked(bool){
    QSettings settings(Company, Softname);
    QString originForDirs =  settings.value("output", QDir::home().path()).toString();

    QString dir_name = QFileDialog::getExistingDirectory(this, QApplication::tr("Choose Directory"),
                                                         originForDirs,
                                                         QFileDialog::ShowDirsOnly
                                                         | QFileDialog::DontResolveSymlinks);
    if(!dir_name.isEmpty()){
        if(!dir_name.endsWith('/')) dir_name.append('/');

        settings.value("output", dir_name);
        ui.labelOutput->setText(dir_name);
    }
}

void PicmizCore::on_buttonTag_clicked(bool){
    QSettings settings(Company, Softname);
    QString originForImage =  settings.value("tag", QDir::home().path()).toString();

    QString file = QFileDialog::getOpenFileName(this ,
                                                      QApplication::tr("Choose Tag"),
                                                      originForImage ,
                                                      QApplication::tr("Images (*.png *.jpg)"));
    if(!file.isEmpty()){
        settings.value("tag", file);

        ui.buttonTag->setText(file);

        clearScene(&tagScene);

        QPixmap pix(file);
        QPixmap pixmini(pix.scaled(ui.viewMiniTag->width() * 0.95,ui.viewMiniTag->height() * 0.95,Qt::KeepAspectRatio,Qt::FastTransformation));
        QGraphicsPixmapItem * picture = tagScene.addPixmap(pixmini);
        picture->setOffset((ui.viewMiniTag->width()-pixmini.width())/2,(ui.viewMiniTag->height()-pixmini.height())/2);
    }
}

////////////////////////// Radio event //////////////////////////////

void PicmizCore::on_radioUseTag_clicked(bool){
    tagWidget(true);
}
void PicmizCore::on_radioNoTag_clicked(bool){
    tagWidget(false);
}
void PicmizCore::tagWidget(bool state){
    ui.buttonTag->setEnabled(state);
    ui.viewMiniTag->setEnabled(state);
    ui.radioLeft->setEnabled(state);
    ui.radioRight->setEnabled(state);
    ui.line->setEnabled(state);
    ui.radioTop->setEnabled(state);
    ui.radioBottom->setEnabled(state);
}

void PicmizCore::on_radioCreateNew_clicked(bool){
    replaceWidget(true);
}
void PicmizCore::on_radioReplace_clicked(bool){
    replaceWidget(false);
}
void PicmizCore::replaceWidget(bool state){
    ui.buttonOutput->setEnabled(state);
    ui.labelOutput->setEnabled(state);
    ui.checkHierarchy->setEnabled(state);
    ui.checkExtension->setEnabled(state);
    ui.lineExtension->setEnabled(state);
    ui.comboTypeFormat->setEnabled(state);
}

////////////////////////// Load/Save //////////////////////////////

void PicmizCore::on_actionSave_Project_triggered ( bool){
    saveProject();
}

// save project
void PicmizCore::saveProject(){
    QFile data(projectFile);
    if (data.open(QFile::WriteOnly | QFile::Truncate)) {
        QTextStream out(&data);
        out << "#Picmiz Generation" << "\n";

        out << "pos=" <<  pos().x() << ";" << pos().y() << "\n";

        out << "#Create new or not" << "\n";
        out << "radioCreateNew=" << ui.radioCreateNew->isChecked() << "\n";

        out << "#Tag" << "\n";
        out << "radioUseTag=" << ui.radioUseTag->isChecked() << "\n";
        out << "buttonTag=" << ui.buttonTag->text() << "\n";
        out << "radioLeft="<< ui.radioLeft->isChecked() << "\n";
        out << "radioTop="<< ui.radioTop->isChecked() << "\n";

        out << "#Size" << "\n";
        out << "widthValue="<< ui.widthValue->value() << "\n";
        out << "heightValue="<< ui.heightValue->value() << "\n";
        out << "checkRatio="<< ui.checkRatio->isChecked() << "\n";
        out << "comboTypeWidth="<< ui.comboTypeWidth->currentIndex() << "\n";
        out << "comboTypeHeight="<< ui.comboTypeHeight->currentIndex() << "\n";

        out << "#Output" << "\n";
        out << "labelOutput="<< ui.labelOutput->text() << "\n";
        out << "checkHierarchy="<isChecked() << "\n";
        out << "checkExtension="<isChecked() << "\n";
        out << "lineExtension="<text() << "\n";
        out << "comboTypeFormat="<currentIndex() << "\n";

        out << "#Images" << "\n";
        for(int indexImage = 0 ; indexImage < images.size() ; ++indexImage){
            out << "Image=" << images[indexImage].name << ";" << images[indexImage].root << ";" << images[indexImage].completePath  << "\n";
        }

        out.flush();
    }
    else{
        qWarning("Cannot save file :");
        qWarning(projectFile.toLatin1());
    }
}

// load a project
void PicmizCore::loadProject(){
    QFile data(projectFile);
    if (data.open(QFile::ReadOnly)) {
        QTextStream in(&data);
        QList tmpimages;

        while(!in.atEnd()){
            QString line = in.readLine();
            if(!line.startsWith("#")){

                QStringList values = line.split("=");
                if(values[0] == "pos") {
                    QStringList position = values[1].split(';');
                    move(QPoint(position[0].toDouble(), position[1].toDouble()));
                }
                else if(values[0] == "radioCreateNew"){
                    ui.radioCreateNew->setChecked(values[1].toInt());
                    ui.radioReplace->setChecked(!ui.radioCreateNew->isChecked());
                    replaceWidget(ui.radioCreateNew->isChecked());
                }
                else if(values[0] == "radioUseTag"){
                    ui.radioUseTag->setChecked(values[1].toInt());
                    ui.radioNoTag->setChecked(!ui.radioUseTag->isChecked());
                    tagWidget(ui.radioUseTag->isChecked());
                }
                else if(values[0] == "buttonTag"){
                    ui.buttonTag->setText(values[1]);
                }
                else if(values[0] == "radioLeft"){
                    ui.radioLeft->setChecked(values[1].toInt());
                    ui.radioRight->setChecked(ui.radioLeft->isChecked());
                }
                else if(values[0] == "radioLeft"){
                    ui.radioTop->setChecked(values[1].toInt());
                    ui.radioBottom->setChecked(ui.radioTop->isChecked());
                }
                else if(values[0] == "widthValue"){
                    ui.widthValue->setValue(values[1].toDouble());
                }
                else if(values[0] == "heightValue"){
                    ui.heightValue->setValue(values[1].toDouble());
                }
                else if(values[0] == "checkRatio"){
                    ui.checkRatio->setChecked(values[1].toInt());
                }
                else if(values[0] == "comboTypeWidth"){
                    ui.comboTypeWidth->setCurrentIndex(values[1].toInt());
                }
                else if(values[0] == "comboTypeHeight"){
                    ui.comboTypeHeight->setCurrentIndex(values[1].toInt());
                }
                else if(values[0] == "labelOutput"){
                    ui.labelOutput->setText(values[1]);
                }
                else if(values[0] == "checkHierarchy"){
                    ui.checkHierarchy->setChecked(values[1].toInt());
                }
                else if(values[0] == "checkExtension"){
                    ui.checkExtension->setChecked(values[1].toInt());
                }
                else if(values[0] == "lineExtension"){
                    ui.lineExtension->setText(values[1]);
                }
                else if(values[0] == "comboTypeFormat"){
                    ui.comboTypeFormat->setCurrentIndex(values[1].toInt());
                }
                else if(values[0] == "Image"){
                    QStringList data = values[1].split(';');
                    Image_t image;

                    image.name = data[0];
                    image.root = data[1];
                    image.completePath = data[2];

                    tmpimages.append(image);
                }
            }
        }

        on_buttonDeleteAll_clicked(true);

        progress->reset();
        progress->show();

        loader.Images(tmpimages);
        loader.start();

    }
    else{
        qWarning("Cannot load file :");
        qWarning(projectFile.toLatin1());
    }
}

// save a project
void PicmizCore::on_actionSave_Project_As_triggered (bool){
    QSettings settings(Company, Softname);
    QString tmpProjectFile =  settings.value("projectFile", QDir::home().path()).toString();

    QString file = QFileDialog::getSaveFileName(this ,
                                                QApplication::tr("Choose Project file"),
                                                tmpProjectFile ,
                                                QApplication::tr("Project (*.pimz)"));
    if(!file.isEmpty()){
        if(!file.endsWith(".pimz")) file.append(".pimz");
        settings.setValue("projectFile",projectFile);

        projectFile = file;
        ui.actionSave_Project->setEnabled(true);
        saveProject();
    }
}

// load a project
void PicmizCore::on_actionLoad_Project_triggered ( bool){
    QSettings settings(Company, Softname);
    QString tmpProjectFile =  settings.value("projectFile", QDir::home().path()).toString();

    QString file = QFileDialog::getOpenFileName(this ,
                                                QApplication::tr("Choose Project file"),
                                                tmpProjectFile ,
                                                QApplication::tr("Project (*.pimz)"));
    if(!file.isEmpty()){
        settings.setValue("projectFile",file);
        projectFile = file;
        loadProject();
    }
}

// About
void PicmizCore::on_actionAbout_Picmiz_triggered(bool){
    QMessageBox::about ( this, QApplication::tr("About"), QApplication::tr("Picmiz, developed by Berenger (<a href="\&quot;http://berenger.eu/picmiz\&quot;">http://berenger.eu/picmiz</a>).
Please, Donate to contact@berenger.eu using paypal.") );
}

// Quit
void PicmizCore::on_actionQuit_triggered(bool){
    close();
}

////////////////////////// Settings //////////////////////////////

// save setting
void PicmizCore::saveSettings(){
    QSettings settings(Company, Softname);

    settings.setValue("pos", pos());

    settings.setValue("radioCreateNew", ui.radioCreateNew->isChecked());

    settings.setValue("radioUseTag", ui.radioUseTag->isChecked());
    settings.setValue("buttonTag", ui.buttonTag->text());
    settings.setValue("radioLeft", ui.radioLeft->isChecked());
    settings.setValue("radioTop", ui.radioTop->isChecked());

    settings.setValue("widthValue", ui.widthValue->value());
    settings.setValue("heightValue", ui.heightValue->value());
    settings.setValue("checkRatio", ui.checkRatio->isChecked());
    settings.setValue("comboTypeWidth", ui.comboTypeWidth->currentIndex());
    settings.setValue("comboTypeHeight", ui.comboTypeHeight->currentIndex());

    settings.setValue("labelOutput", ui.labelOutput->text());
    settings.setValue("checkHierarchy",ui.checkHierarchy->isChecked());
    settings.setValue("checkExtension",ui.checkExtension->isChecked());
    settings.setValue("lineExtension",ui.lineExtension->text());
    settings.setValue("comboTypeFormat",ui.comboTypeFormat->currentIndex());

}

// laod setting
void PicmizCore::loadSettings(){
    QSettings settings(Company, Softname);

    move(settings.value("pos",pos()).toPoint());

    move(QPoint(150,150));

    ui.radioCreateNew->setChecked(settings.value("radioCreateNew", ui.radioCreateNew->isChecked()).toBool());
    ui.radioReplace->setChecked(!settings.value("radioCreateNew", ui.radioCreateNew->isChecked()).toBool());
    replaceWidget(ui.radioCreateNew->isChecked());

    ui.radioUseTag->setChecked(settings.value("radioUseTag", ui.radioUseTag->isChecked()).toBool());
    ui.radioNoTag->setChecked(!settings.value("radioUseTag", ui.radioUseTag->isChecked()).toBool());
    tagWidget(ui.radioUseTag->isChecked());
    ui.buttonTag->setText(settings.value("buttonTag", ui.buttonTag->text()).toString());
    ui.radioLeft->setChecked(settings.value("radioLeft", ui.radioLeft->isChecked()).toBool());
    ui.radioTop->setChecked(settings.value("radioTop", ui.radioTop->isChecked()).toBool());
    ui.radioRight->setChecked(!settings.value("radioLeft", ui.radioLeft->isChecked()).toBool());
    ui.radioBottom->setChecked(!settings.value("radioTop", ui.radioTop->isChecked()).toBool());

    clearScene(&tagScene);
    QPixmap pix(ui.buttonTag->text());
    QPixmap pixmini(pix.scaled(ui.viewMiniTag->width() * 0.95,ui.viewMiniTag->height() * 0.95,Qt::KeepAspectRatio,Qt::FastTransformation));
    QGraphicsPixmapItem * picture = tagScene.addPixmap(pixmini);
    picture->setOffset((ui.viewMiniTag->width()-pixmini.width())/2,(ui.viewMiniTag->height()-pixmini.height())/2);

     ui.widthValue->setValue(settings.value("widthValue", ui.widthValue->value()).toDouble());
    ui.heightValue->setValue(settings.value("heightValue", ui.heightValue->value()).toDouble());
    ui.checkRatio->setChecked(settings.value("checkRatio", ui.checkRatio->isChecked()).toBool());
    ui.comboTypeWidth->setCurrentIndex(settings.value("comboTypeWidth", ui.comboTypeWidth->currentIndex()).toInt());
    ui.comboTypeHeight->setCurrentIndex(settings.value("comboTypeHeight", ui.comboTypeHeight->currentIndex()).toInt());

    ui.labelOutput->setText(settings.value("labelOutput", ui.labelOutput->text()).toString());
    ui.checkHierarchy->setChecked(settings.value("checkHierarchy",ui.checkHierarchy->isChecked()).toBool());
    ui.checkExtension->setChecked(settings.value("checkExtension",ui.checkExtension->isChecked()).toBool());
    ui.lineExtension->setText(settings.value("lineExtension",ui.lineExtension->text()).toString());
    ui.comboTypeFormat->setCurrentIndex(settings.value("comboTypeFormat",ui.comboTypeFormat->currentIndex()).toInt());
}

Licence & source

Picmiz is a free software under LGPL  (http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License).

You have to say in your program if you take some information from this page and you your program has to be licensed under LGPL too.

Please leave a comment if you find this code useful.

The source : PicmizSource

Enjoyed reading this post?
Subscribe to the RSS feed and have all new posts delivered straight to you.

Comments are closed.

Celadon theme by the Themes Boutique