понедельник, 31 августа 2015 г.

iMusicLibrary or how to delete music from hard drive in iTunes.

Suppose you downloaded your super music to your iDevice, listen it, rate every song and after this you want to delete every track with low rating from your iDevice, and also from your hard drive too. Of course you can easily delete music from iDevice, but unfortunately iTunes can't delete tracks from your file system, so what we should to do?

We can delete every file manually, but it is so boring! This program allows you to do that without headache! It parses iTunes library file and show all result in a way very similar to iTunes (see screenshots below). Also you can get information about file, listen it with default player in your system and also move file to the recycle bin (delete file). Additional features allows you to sort table by artist, album, rating, etc., search for particular song using also all power of a regular expression (for advanced users).

It is very easy to use:

  • choose your iTunes Music Library.xml file (program will try to find directory with this file automatically);
  • open it and wait (parsing of a large music database can be long); 
  • search all needed tracks and do some actions with them. 


For example, sort table by rating, select all songs with one star rating, right-click, press move to recycle bin, confirm, wait for a moment, ??? , profit! User interface is pretty similar to iTunes, so I hope you will adapt very quickly.

There is the sampleiTunes Music Library.xml file in the archieve, which I used to create screenshots, you can open this file in program to get same result on your computer.

Screenshots







To run this app, just unzip this archive. Also it can be started without unzipping. For advanced users: as you know several apps can use same .dll files, so if you have my another apps, you can use dll with same names without errors. For example one Qt5Widgets.dll can serve all my apps, so you don't need to use 5 Qt5Widgets.dll for 5 .exe.

Author (e-mail): chernobyllab@yandex.ru



пятница, 7 августа 2015 г.

C++ Tale about mutable keyword. Part 3

It is the last chapter of our tale about mutable keyword in C++. You can check first and second chapter before reading this one.

Let's talk about mutable and templates. Consider next code.
template< typename T >
class X {
    T i;
public:
    X ( T val ):i(val){}

    void printMember() const
    {
        std::cout << "i = " << i << std::endl;
    }

    void changeMember(const T & val) const
    {
        i = val;
    }

};

int main(int argc, char *argv[])
{
    X < int > x( 9 );
    x.printMember();
}
If you think, that this code will not compile, then you are... wrong! You should remember, that compiler will not generate template code if you don't use it directly in your program. It is defends you from creating unnecessary functions and of course reduce compile time. But I agree, it is very dirty trick and has nothing to do with mutable . So next code is not correct.
template< typename T >
class X {
    /*mutable*/ T i;
public:
    X ( T val ):i(val){}

    void printMember() const
    {
        std::cout << "i = " << i << std::endl;
    }

    void changeMember(const T & val) const
    {
        i = val;//error
    }

};

int main(int argc, char *argv[])
{
    X < int > x( 9 );
    x.printMember();
    x.changeMember( 18 );
    x.printMember();
}
Here we use changeMember() method and compiler generates error, but uncomment mutable keyword and all will be fine. So as you can see mutable behaves in templates as usual. So our journey to the mutable world ends, but it has continuation in modern C++ world!

So now we will talk about lambdas and where mutable can be suitable here. So consider next code.
int main(int argc, char *argv[])
{
    int i = 42;
    auto lambdaByValue = [i]
    {
        std::cout << "i = " << i << std::endl;//i = 42
    };
    lambdaByValue();

    auto lambdaByRef = [&i]
    {
        i = 9;
        std::cout << "i = " << i << std::endl;//i = 9
    };
    lambdaByRef();

    std::cout << "i = " << i << std::endl;    //i = 9

    auto lambdaByValueChange = [i]
    {
        i = 9;//error: assignment of read-only variable 'i'
        std::cout << "i = " << i << std::endl;
    };
    lambdaByValueChange();
}
As you can see, there is one error here, but why? As we know, lambda it's a class with the overloaded operator(). But the most important detail here, is that this operator() is const by default! It means that next code is equivalent to our lambdaByValue and lambdaByValueChange lambdas.
class LambdaByValue
{
private:
    int i;
public:
    void operator () () const
    {
        std::cout << "i = " << i << std::endl;//Ok
    }
};

class LambdaByValueChange
{
private:
    int i;
public:
    void operator () () const
    {
        i = 9;//error: assignment of member 'LambdaByValueChange::i' in read-only object
        std::cout << "i = " << i << std::endl;
    }
};
As you can see, it is just a class member and we try to change it in const member function. Of course it is wrong and as you know, we can add mutable keyword to make this example correct, but in real code you can't access generated by compiler lambda code, so what can we do to solve this problem? C++ standard allows us to create mutable lambda, it is usual lambda, but with mutable keyword. So probably you think, that in this case compiler will add mutable keyword to every class member like this:
class LambdaByValueChange
{
private:
    mutable int i;
public:
    void operator () () const
    {
        i = 9;//Ok
        std::cout << "i = " << i << std::endl;
    }
};
But it is not a truth, compiler just generate non-const operator() and it means that you can easily change whatever you want inside this operator. Finally, equivalent to mutable lambda code is:
class LambdaByValueChange
{
private:
    int i;
public:
    void operator () ()
    {
        i = 9;//Ok
        std::cout << "i = " << i << std::endl;
    }
};
General rule for such lambdas is:
[ capture ] ( params ) mutable exception attribute -> ret { body }
So our final working example will be:
int main(int argc, char *argv[])
{
    int i = 42;
    auto lambdaByValue = [i]
    {
        std::cout << "i = " << i << std::endl;//i = 42
    };
    lambdaByValue();

    auto lambdaByRef = [&i]
    {
        i = 9;
        std::cout << "i = " << i << std::endl;//i = 9
    };
    lambdaByRef();

    std::cout << "i = " << i << std::endl;    //i = 9

    //we can't skip ()
    auto lambdaByValueChange = [i] () mutable
    {
        i = 3;
        std::cout << "i = " << i << std::endl; //i = 3
    };
    lambdaByValueChange();
}
Also, if you want to use mutable , you can't skip () in lambda anymore.

It seems that it is final part of our tale, because I couldn't find another interesting facts about mutable in C++ standard. If I will find something interesting about mutable again, I will write another part, but if you know something interesting about mutable which was not covered here, please share your knowledge, it will be great!

пятница, 31 июля 2015 г.

C++ Tale about mutable keyword. Part 2

So it is a second part of our tale about mutable keyword in C++. From the first part we know that the mutable specifier on a class data member nullifies a const specifier applied to the containing class object and permits modification of the mutable class member even though the rest of the object is const . It means that next code has one error.
class X {
public:
    X (int x, int y): a(x), b(y){}
    mutable int a;
    int b;
};

int main(int argc, char *argv[])
{
    X x( 10, 10 );
    x.a = 42;
    x.b = 42;

    const X cx( 10, 10 );
    cx.a = 42;//Ok, because a is mutable
    cx.b = 42;//error: assignment of member 'X::b' in read-only object
}
But there is one situation where you can't change class member even if it mutable . To be honest this problem is not very practical, but it is just interesting. I will refresh your knowledge about pointers to member. Also you can find more information here.
struct Foo {
    Foo() : i(0) { }
    int i;
};

int main(int argc, char *argv[])
{
    Foo foo1;
    Foo foo2;
    foo2.i = 12;
    Foo foo3;
    int Foo::*pm = & Foo::i;//get pointer

    foo3.*pm = 42;//and now we can change class member with pm

    std::cout << foo1.*pm  << std::endl;//prints 0
    std::cout << foo2.*pm  << std::endl;//prints 12
    std::cout << foo3.*pm  << std::endl;//prints 42
    std::cout << foo3.i  << std::endl;  //prints 42

    //same with usual pointers
    Foo* pfoo = new Foo;
    std::cout << pfoo->*pm  << std::endl;//prints 0
    pfoo->*pm = 9;
    std::cout << pfoo->*pm  << std::endl;//prints 9
}
So consider next code:
struct Foo {
    Foo() : i(0) { }
    int i;
};
void f()
{
    /*const*/ Foo cs;
    int Foo::* pm = & Foo::i;
    cs.*pm = 88;
}
It is correct, but uncomment const specifier and you will get error. You can say: "Of course, it is const object! We can't change it, we should at least add mutable  keyword and all will be fine!". But unfortunately not, it is forbidden by C++ standard. Here is a quote: "it is not possible to use a pointer to member that refers to a mutable member to modify a const class object". For example:
struct Foo {
    Foo() : i(0) { }
    mutable int i;
};
void f()
{
    const Foo cs;
    int Foo::* pm = & Foo::i; // pm refers to mutable member Foo::i
    cs.*pm = 88; // ill-formed: cs is a const object
}
As you can see, it is not so simple and mutable keyword is pretty interesting. And it is the end of second part, but it will be third. Yeah, there are more interesting things about mutable ;)

воскресенье, 28 июня 2015 г.

C++ Tale about mutable keyword. Part 1

There is one beautiful keyword in C++ which called mutable. Today we will see how, where and when we can use it. I will not write about very basic things that you can read in any other blog, I just hope that you know that we can easily modify mutable members inside const member functions. So where we can apply this keyword? Consider next code:
class X {
    mutable const int a;
    mutable const int* b;
    mutable static int c;
    mutable int* const d;
    mutable const std::string& e;
    mutable volatile bool f;
};

int main(int argc, char *argv[])
{
}
Can you tell result of compilation? Which lines are correct and which are wrong? As you can see, there is no something primitive like mutable int var; here, so it is not so easy. The answer is next:
class X {
    mutable const int a;            //Wrong
    mutable const int* b;           //Correct
    mutable static int c;           //Wrong
    mutable int* const d;           //Wrong
    mutable const std::string& e;   //Wrong
    mutable volatile bool f;        //Correct
};

And of course explanation.
mutable const int a;
Short answer, C++ Standard forbids this. But also this line just has no sense! We use mutable when we want change class member inside const member function, but mutable const means that our member now is totally const, it cannot be modified at all, nor in const member function, nor in non-const!

mutable const int* b;
To solve this little puzzle you should know distinguish between const int* and int* const. If you don't know this, please click here. In this line b is pointer TO const, it is NOT a const pointer, so it is not a const class member and of course it is correct. mutable here has sense because it allows us to change pointer inside const member functions.

mutable static int c;
Again C++ Standard forbids this, but I will prove you that this line has no any sense too. Consider next code:
class Y {
    static int si;
    int i;

    void changeClassMembers() const
    {
        si = 42;//Ok
        i  = 42;//compiler error
    }
};
As you can see, we can't change i in const member function, of course. But changing the static variable inside this function is not error, it is fully correct! Main idea is that static class members can be changed inside const member functions, so these variables don't need mutable keyword at all! General rule is that const member function shall not modify the object and its non-static data members. For more information, see this question on Stack Overflow
mutable int* const d;
This question is similar to the second case and here we deal with const pointer, i.e. const class member, so it is forbidden and has no sense (as we seen in first question). So I hope that you understand that mutable const int* const d; is a const pointer to const int and it will not compile too.
mutable const std::string& e;
It is also wrong, because we can't apply mutable to the reference. e here is a reference, so of course it will not compile.
mutable volatile bool f;
And finally last line is correct. mutable can be used with the volatile, it is not forbidden.

Conclusion. As C++ standard said: "The mutable specifier can be applied only to names of class data members (9.2) and cannot be applied to names declared const or static, and cannot be applied to reference members."

Part 2 will be soon.

вторник, 14 апреля 2015 г.

How to use templates with Qt signals and slots?


As you know, Qt doesn't allow templates in signals and slots. If you didn't know about that and you want read explanation, read following link. Ok, but what if you have a few somethingChanged signals with different signatures (see listing below) but you want create same handling of these signals.
void dateTimeChanged(const QDateTime & datetime)
void valueChanged(int value)
void textChanged(const QString & text)
Something like next slot will be very suitable for our purpose:
private slots:
    template < typename T >
    void handle( T data);
But it is forbidden in Qt, so what we should to do? Create 3 slots with different signatures and same code? Fortunately no, we can create something like template. Qt5 offers us new syntax and slots syntax which can be very suitable for us, because it has possibility to automatically cast the types if there is implicit conversion (e.g. from QString to QVariant).

So we should create slot with QVariant and we will be able to use this slot with another signals. Fortunately QVariant has implicit conversion for many types. Let's create example application with QDateTimeEdit QSlider QLineEdit which emit smthChanged signals. To handle all these signals we will create function process which takes QVariant and prints signal's message to the QTextEdit.
Next code was written to be fully copy-pasted without any changes (just write nessecary includes if you don't have it)
/* we can't use object before QApplication so we use pointer, 
 * but we should allocate memory before we will use this pointer
 */
QTextEdit *textEdit;

void process( QVariant var )
{
    textEdit->append(var.toString());
    qDebug() << var.toString();
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QVBoxLayout *layout = new QVBoxLayout;
    QWidget *mainWidget = new QWidget;

    QDateTimeEdit *dateTimeEdit = new QDateTimeEdit(mainWidget);
    QSlider *slider = new QSlider(mainWidget);
    QLineEdit *lineEdit = new QLineEdit(mainWidget);

    //connection with new Qt5 syntax, also we should explicitly use QObject::
    QObject::connect(dateTimeEdit,& QDateTimeEdit::dateTimeChanged, process);
    QObject::connect(slider,& QSlider::valueChanged, process);
    QObject::connect(lineEdit,& QLineEdit::textChanged, process);

    //just to create smaller code we add widgets to the layout in foreach loop
    foreach ( QWidget * widget, mainWidget->findChildren< QWidget* >( QString() , Qt::FindDirectChildrenOnly )) {
        layout->addWidget(widget);
    }

    textEdit = new QTextEdit;
    layout->addWidget(textEdit, 10 ); //here we use stretch

    mainWidget->setLayout(layout);
    mainWidget->show();
    return a.exec();
}
And result:


As you can see, we created more general code without direct using of templates. Corresponding answer on stackoverflow: http://stackoverflow.com/questions/26950718/how-to-use-templates-with-qt-signals-and-slots/

среда, 18 февраля 2015 г.

Qt QtConcurrent: filtered, shortest example with C++11 and lambda expressions

I noticed that all available examples with this extremely useful thing (filtered) is so long... Can we create fully working example with a few lines of code? The answer is of course!
 
If you don't know what is it and why is it useful, then see description in documentation: 

http://doc.qt.io/qt-5/qtconcurrent.html#filtere


About filtered: as you can see, we need Sequence and FilterFunction. In our example Sequence will be QVector<int> and FilterFunction will be lambda. I assume that next code you will wrote inside main() function or inside constructor or method of some class.

QVector<int> vec;
for (int i = 1; i < 11; ++i) {
    vec.append(i);//fill vector with 1,2,3,...
}

QFuture<int> future = QtConcurrent::filtered(/*our Sequence*/ vec,/*our FilterFunction*/[=] (const int& x)
{
    QThread::sleep( 10 );//you can skip this, but it will show you that main thread and user interface will not hang
    return x % 2 == 0;
});
QFutureWatcher<int> *watcher = new QFutureWatcher<int>;
//we need this to grab result when all will be done
QObject::connect(watcher,& QFutureWatcher<int>::finished,[=] () {qDebug() <<"Result: "<< future.results();});
watcher->setFuture(future);
Output:
"Result:  (2, 4, 6, 8, 10)"
Just a few lines without classes or separate functions, only with lambdas and new syntax of signals and slots(only for Qt5!). But don't forget that you should add to your .pro file:
QT       += concurrent
CONFIG   += c++11

воскресенье, 8 февраля 2015 г.

QSolarSystem2D (Qt/QML simple 2D solar system simulator)

QSolarSystem2D


QSolarSystem2D is the open source simple simulator of solar system which shows you properly scaled distance between planets. Planets are animated with proper rotation periods.
 


In this program you can:

  • Pause/play animation by pressing special button or right mouse button
  • Zoom in or zoom out animation by wheel
  • Highlight every planet or Sun by hovering the cursor on picture in the left table


There is table in the left side which contains small image of planet, name and current number of rotation.

Download: https://yadi.sk/d/nFEDliXgeYZmR

To run this app, just unzip this archive. Also it can be started without unzipping. For advanced users: as you know several apps can use same .dll files, so if you have my another apps, you can use dll with same names without errors. For example one Qt5Widgets.dll can serve all my apps, so you don't need to use 5 Qt5Widgets.dll for 5 .exe.

Source on the GitHub: https://github.com/chernobyllab/QSolarSystem2D

To build this app from source: just clone repository and run QSolarSystem2D.pro file in your Qt Creator.

This programm was written with C++/Qt/QML. It is quite simple and was written to learn QML.

Screenshots





Video



Author (e-mail): chernobyllab@yandex.ru
Author (blog): http://chernobyllab.blogspot.com/