вторник, 26 июня 2012 г.

subversion 1.7 в kubuntu 12.04 (precise)

Для установки subversion 1.7 в kubuntu 12.04 (precise) необходимо добавить в файл /etc/apt/sources.list строку
deb http://ppa.launchpad.net/dominik-stadler/subversion-1.7/ubuntu precise main

Далее выполнить установку или обновление пакета subversion

sudo aptitude update
sudo aptitude install subversion (sudo aptitude safe-upgrade)

вторник, 19 июня 2012 г.

Заморозка GUI в Qt

Для решения проблем заморозки GUI и реализации отзывчивых приложений необходимо придерживаться советов из следующих статей:
http://doc.qt.nokia.com/qq/qq27-responsive-guis.html
http://qt-project.org/wiki/Progress-bar

Класс для выполнения длительных операций в отдельном потоке с выводом QProgressBar:

file.h



typedef boost::function< void () > BusyFunction;

class Busy : public QObject
{
    Q_OBJECT

public:

    Busy( const QString& label
          , const BusyFunction& longOperationFunction
          , QWidget* parentWidget );
 
private:
 
    void start();
 
private:

    CONST_PROPERTY( QPointer< QFutureWatcher< void > >
                    , watcher );
 
    CONST_PROPERTY( QPointer< QProgressDialog >, progress );

    CONST_PROPERTY( BusyFunction, longOperationFunction );
};


file.cpp


Busy::Busy( const QString& label
            , const BusyFunction& longOperationFunction
            , QWidget* parentWidget )
    : QObject()
      , INIT_PROPERTY( watcher, new QFutureWatcher< void >( this ) )
      , INIT_PROPERTY( progress
                       , new QProgressDialog( label, QString(), 0, 0
                                              , parentWidget ) )
      , INIT_PROPERTY( longOperationFunction, longOperationFunction )
{
    this->progress()->setWindowFlags( Qt::Tool | Qt::CustomizeWindowHint
                                          | Qt::WindowTitleHint );
 
    this->progress()->setWindowModality( Qt::WindowModal );

    this->progress()->setCancelButton( 0 );

    connect( this->watcher(), SIGNAL( finished() )
             , this->progress(), SLOT( cancel() ) );

    this->start();
}

void Busy::start()
{
    QFuture< void > future = QtConcurrent::run( this->longOperationFunction() );

    this->watcher()->setFuture( future );

    this->progress()->exec();
}


preocessEvents из дополнительного потока Qt

В qt нельзя вызвать processEvents из другого (не gui) потока. При создании потока и связи сигнала этого потока со слотом главного потока посредством connect через Qt::DirectConnection, слот будет выполняться в дополнительном потоке. Проверить принадлежность к потоку можно вызовом QThread::currentThread(). В связи с этим вызов метода QApplication::processEvents() из слота не предпримет никаких действий, т.к. для дополнительного потока очередь gui событий будет пуста. (QApplication::hasPendingEvents() вернет false).

понедельник, 4 июня 2012 г.

Хранение GUI настроек окна в Qt4

В виду особенностей X11 не рекомендуется для хранения геометрии окна использовать метод QWidget::geometry() и восстанавливать методом QWidget::setGeometry(). Вместо этого нужно использовать QRect( QWidget::pos(), QWidget::size() ) и восстанавливать через QWidget::move() и QWidget::resize();

links:
http://qt-project.org/doc/qt-4.8/application-windows.html
http://qt-project.org/doc/qt-4.8/qsettings.html

вторник, 15 мая 2012 г.

#include "" и INCLUDEPATH

В файлах #include нужно указывать относительно текущего файла. В таком случае includepath можно не указывать, компилятор производит автоматический поиск относительно компилируемого файла.

Например,
src
    - first
        - signal.h
        - first.cpp
    - second
        - signal.h
    - main
        - main.cpp

main.cpp
#include "../first/signal.h" // правильно
#include "../second/signal.h" // правильно

first.cpp
#include "signal.h" //правильно, равно first/signal.h, вне зависимости от includepath

Но если main.cpp будет такого вида:
#include "signal.h" // неверно, хотя и будет работать, если установлен INCLUDEPATH
и присутствует includepath, то выберется тот signal.h, папка которого находится раньше в includepath.

По мере разрастания проекта или выделения библиотеки позволяется для поиска хедеров в определенной директории установить INCLUDEPATH.

http://www.mingw.org/wiki/IncludePathHOWTO

Ограничение mingw на уровень вложенности хедера

Необъяснимое ограничение в mingw количество уровней вложенности файлов, включаемых через #include. Ошибка: no such file or directory.

Например, file.cpp
#include "../../../../../../../some_path/maybe_yet_path/file2.h"

При компиляции в win не находить файл file2.h, хотя в линуксе все норм. Критическое количество уровней не определял. Может из-за длины имени файла, но вроде ntfs, да и путь не такой уж длинный.

понедельник, 14 мая 2012 г.

pysvn + sasl + ldap

Проблема.
После перевода сервера svn на режим аутентификации sasl + ldap перестал работать модуль pysvn на windows машинах. Вываливался с ошибкой: cannot negotiate authentication mechanism. Очевидно subversion библиотеки, которые с ним поставляются, скомпилированы без поддержки sals + ldap.

Решение.
Необходимо установить пакет консольных утилит subversion от кампании wandisco (или другой, лишь бы была поддержка sasl + ldap), добавить в переменную окружения PATH путь к wandisco, далее скопировать все динамические библиотеки (dll) из wandisco в папку, куда установлен pysvn (по умолчанию, python/lib/site-packages/pysvn). После этого должно заработать.
ps Замечено, что при удалении или переименовании wandisco перестает работать pysvn. Не удаляйте wandisco. Костыли конечно.