summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2010-09-05 04:36:48 +0200
committerVegard Storheil Eriksen <zyp@jvnv.net>2010-09-05 04:36:48 +0200
commit9dac6d187810915895ac9f7a6b739ff818336b35 (patch)
treeae3c3c87bd05972fbb1cea7f5f77151a206d4c18
Initial import.
-rw-r--r--SConstruct35
-rw-r--r--default.qss33
-rw-r--r--gui/browser.cpp2
-rw-r--r--gui/browser.h13
-rw-r--r--gui/mainwindow.cpp45
-rw-r--r--gui/mainwindow.h29
-rw-r--r--gui/mainwindow.ui174
-rw-r--r--main.cpp28
-rw-r--r--player.cpp49
-rw-r--r--player.h36
-rw-r--r--qt4.py538
11 files changed, 982 insertions, 0 deletions
diff --git a/SConstruct b/SConstruct
new file mode 100644
index 0000000..5bafdd7
--- /dev/null
+++ b/SConstruct
@@ -0,0 +1,35 @@
+import os
+
+env = Environment(
+ ENV = os.environ,
+)
+
+env.Tool('qt4', toolpath = '.')
+
+AddOption('--release', action = 'store_true')
+AddOption('--profiling', action = 'store_true')
+
+if env['PLATFORM'] == 'darwin':
+ env.Append(CPPFLAGS = '-m32')
+ env.Append(LINKFLAGS = '-m32')
+ env.Append(FRAMEWORKS = ['phonon'])
+#else:
+ #env.Append(CPPPATH = [])
+ #env.Append(LIBS = [])
+
+if not GetOption('release'):
+ env.Append(CPPFLAGS = ['-Wall', '-g'])
+
+if GetOption('profiling'):
+ env.Append(CPPFLAGS = ['-pg'])
+ env.Append(LINKFLAGS = ['-pg'])
+
+Export('env')
+
+env.EnableQt4Modules(['QtCore', 'QtGui'], debug = False)
+
+env.Uic4(Glob('gui/*.ui'))
+
+env.Program('ongaku', Glob('*.cpp') + Glob('gui/*.cpp'))
+
+# vim: syn=python
diff --git a/default.qss b/default.qss
new file mode 100644
index 0000000..7217fd5
--- /dev/null
+++ b/default.qss
@@ -0,0 +1,33 @@
+QSlider::groove:horizontal {
+ border: 1px solid #999999;
+ height: 8px;
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4);
+ margin: 2px 0;
+ border-radius: 5px;
+}
+
+QSlider::handle:horizontal {
+ background: #ffffff;
+ border: 1px solid #ffffff;
+ width: 6px;
+ margin: 0;
+ border-radius: 4px;
+}
+
+#button_prev, #button_next {
+ background: red;
+ width: 27px;
+ height: 27px;
+ border-radius: 15px;
+}
+
+#button_pause, #button_play {
+ background: red;
+ width: 37px;
+ height: 37px;
+ border-radius: 20px;
+}
+
+#button_prev:pressed, #button_pause:pressed, #button_play:pressed, #button_next:pressed {
+ background: green;
+}
diff --git a/gui/browser.cpp b/gui/browser.cpp
new file mode 100644
index 0000000..681039d
--- /dev/null
+++ b/gui/browser.cpp
@@ -0,0 +1,2 @@
+#include "browser.h"
+
diff --git a/gui/browser.h b/gui/browser.h
new file mode 100644
index 0000000..72c5447
--- /dev/null
+++ b/gui/browser.h
@@ -0,0 +1,13 @@
+#ifndef BROWSER_H
+#define BROWSER_H
+
+#include <QtGui>
+
+class Browser : public QWidget {
+ public:
+ Browser(QWidget* p) : QWidget(p) {
+
+ }
+};
+
+#endif
diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
new file mode 100644
index 0000000..28def13
--- /dev/null
+++ b/gui/mainwindow.cpp
@@ -0,0 +1,45 @@
+#include "mainwindow.h"
+
+MainWindow::MainWindow() {
+ //setAttribute(Qt::WA_MacBrushedMetal, true);
+ setupUi(this);
+
+ connect(button_prev, SIGNAL(clicked()), SIGNAL(prev()));
+ connect(button_pause, SIGNAL(clicked()), SIGNAL(pause()));
+ connect(button_play, SIGNAL(clicked()), SIGNAL(play()));
+ connect(button_next, SIGNAL(clicked()), SIGNAL(next()));
+
+ connect(slider_seek, SIGNAL(sliderReleased()), SLOT(slider_released()));
+
+ button_pause->hide();
+}
+
+void MainWindow::update_track(const QUrl& track) {
+
+}
+
+void MainWindow::update_state(bool playing) {
+ if(playing) {
+ button_play->hide();
+ button_pause->show();
+ } else {
+ button_pause->hide();
+ button_play->show();
+ }
+}
+
+void MainWindow::update_pos(int pos) {
+ label_pos->setText(QString("%1:%2").arg(pos / 60).arg(pos % 60, 2, 10, QChar('0')));
+ if(!slider_seek->isSliderDown()) {
+ slider_seek->setValue(pos);
+ }
+}
+
+void MainWindow::update_length(int length) {
+ label_length->setText(QString("%1:%2").arg(length / 60).arg(length % 60, 2, 10, QChar('0')));
+ slider_seek->setMaximum(length);
+}
+
+void MainWindow::slider_released() {
+ emit seek(slider_seek->value());
+}
diff --git a/gui/mainwindow.h b/gui/mainwindow.h
new file mode 100644
index 0000000..e61b405
--- /dev/null
+++ b/gui/mainwindow.h
@@ -0,0 +1,29 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "ui_mainwindow.h"
+
+class MainWindow : public QWidget, private Ui::MainWindow {
+ Q_OBJECT
+
+ public:
+ MainWindow();
+
+ public slots:
+ void update_track(const QUrl& track);
+ void update_state(bool playing);
+ void update_pos(int pos);
+ void update_length(int length);
+
+ private slots:
+ void slider_released();
+
+ signals:
+ void prev();
+ void pause();
+ void play();
+ void next();
+ void seek(int pos);
+};
+
+#endif
diff --git a/gui/mainwindow.ui b/gui/mainwindow.ui
new file mode 100644
index 0000000..2c25920
--- /dev/null
+++ b/gui/mainwindow.ui
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QWidget" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>727</width>
+ <height>519</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Hei morn</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="frame_top">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSplitter" name="splitter">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QFrame" name="frame_left">
+ <property name="maximumSize">
+ <size>
+ <width>200</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTreeWidget" name="treeWidget">
+ <property name="dragDropMode">
+ <enum>QAbstractItemView::InternalMove</enum>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="headerHidden">
+ <bool>true</bool>
+ </property>
+ <column>
+ <property name="text">
+ <string>1</string>
+ </property>
+ </column>
+ <item>
+ <property name="text">
+ <string>Fisk</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Playlists</string>
+ </property>
+ <item>
+ <property name="text">
+ <string>Kake</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Brød</string>
+ </property>
+ </item>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="Browser" name="browser" native="true"/>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame_bottom">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QToolButton" name="button_prev">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="button_pause">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="button_play">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="button_next">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_pos">
+ <property name="text">
+ <string>0:00</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="slider_seek">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_length">
+ <property name="text">
+ <string>0:00</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Browser</class>
+ <extends>QWidget</extends>
+ <header>browser.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..0126575
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,28 @@
+#include <QtGui>
+
+#include "player.h"
+#include "gui/mainwindow.h"
+
+int main(int argc, char** argv) {
+ QApplication qapp(argc, argv);
+
+ qapp.setStyleSheet("file:///default.qss");
+
+ Player* player = new Player();
+
+ MainWindow* mainwindow = new MainWindow();
+ mainwindow->show();
+
+ player->connect(mainwindow, SIGNAL(prev()), SLOT(prev()));
+ player->connect(mainwindow, SIGNAL(pause()), SLOT(pause()));
+ player->connect(mainwindow, SIGNAL(play()), SLOT(play()));
+ player->connect(mainwindow, SIGNAL(next()), SLOT(next()));
+ player->connect(mainwindow, SIGNAL(seek(int)), SLOT(seek(int)));
+
+ mainwindow->connect(player, SIGNAL(changed_track(const QUrl&)), SLOT(update_track(const QUrl&)));
+ mainwindow->connect(player, SIGNAL(changed_state(bool)), SLOT(update_state(bool)));
+ mainwindow->connect(player, SIGNAL(changed_pos(int)), SLOT(update_pos(int)));
+ mainwindow->connect(player, SIGNAL(changed_length(int)), SLOT(update_length(int)));
+
+ qapp.exec();
+}
diff --git a/player.cpp b/player.cpp
new file mode 100644
index 0000000..8419d8c
--- /dev/null
+++ b/player.cpp
@@ -0,0 +1,49 @@
+#include "player.h"
+
+Player::Player() {
+ mo = new Phonon::MediaObject();
+ ao = new Phonon::AudioOutput(Phonon::MusicCategory);
+ Phonon::createPath(mo, ao);
+
+ mo->setTickInterval(100);
+
+ connect(mo, SIGNAL(tick(qint64)), SLOT(tick(qint64)));
+ connect(mo, SIGNAL(totalTimeChanged(qint64)), SLOT(newlength(qint64)));
+}
+
+void Player::prev() {
+
+}
+
+void Player::pause() {
+ mo->pause();
+ emit changed_state(false);
+}
+
+void Player::play() {
+ static bool kake = false;
+
+ if(!kake) {
+ kake = true;
+ mo->setCurrentSource(*(new Phonon::MediaSource("historie.tta")));
+ }
+
+ mo->play();
+ emit changed_state(true);
+}
+
+void Player::next() {
+
+}
+
+void Player::seek(int pos) {
+ mo->seek(pos * 1000);
+}
+
+void Player::tick(qint64 time) {
+ emit changed_pos(time / 1000);
+}
+
+void Player::newlength(qint64 length) {
+ emit changed_length(length / 1000);
+}
diff --git a/player.h b/player.h
new file mode 100644
index 0000000..12437d4
--- /dev/null
+++ b/player.h
@@ -0,0 +1,36 @@
+#ifndef PLAYER_H
+#define PLAYER_H
+
+#include <QObject>
+#include <phonon/mediaobject.h>
+#include <phonon/audiooutput.h>
+
+class Player : public QObject {
+ Q_OBJECT
+
+ private:
+ Phonon::MediaObject* mo;
+ Phonon::AudioOutput* ao;
+
+ private slots:
+ void tick(qint64 time);
+ void newlength(qint64 length);
+
+ public:
+ Player();
+
+ public slots:
+ void prev();
+ void pause();
+ void play();
+ void next();
+ void seek(int pos);
+
+ signals:
+ void changed_track(const QUrl& track);
+ void changed_state(bool playing);
+ void changed_pos(int pos);
+ void changed_length(int length);
+};
+
+#endif
diff --git a/qt4.py b/qt4.py
new file mode 100644
index 0000000..3f2d3a0
--- /dev/null
+++ b/qt4.py
@@ -0,0 +1,538 @@
+# Found at http://clam-project.org/clam/trunk/CLAM/scons/sconstools/qt4.py
+# Made some changes.
+
+"""SCons.Tool.qt
+
+Tool-specific initialization for Qt.
+
+There normally shouldn't be any need to import this module directly.
+It will usually be imported through the generic SCons.Tool.Tool()
+selection method.
+
+"""
+
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os.path
+import re
+
+import SCons.Action
+import SCons.Builder
+import SCons.Defaults
+import SCons.Scanner
+import SCons.Tool
+import SCons.Util
+
+class ToolQt4Warning(SCons.Warnings.Warning):
+ pass
+
+class GeneratedMocFileNotIncluded(ToolQt4Warning):
+ pass
+
+class QtdirNotFound(ToolQt4Warning):
+ pass
+
+SCons.Warnings.enableWarningClass(ToolQt4Warning)
+
+qrcinclude_re = re.compile(r'<file>([^<]*)</file>', re.M)
+
+def transformToWinePath(path) :
+ return os.popen('winepath -w "%s"'%path).read().strip().replace('\\','/')
+
+header_extensions = [".h", ".hxx", ".hpp", ".hh"]
+if SCons.Util.case_sensitive_suffixes('.h', '.H'):
+ header_extensions.append('.H')
+# TODO: The following two lines will work when integrated back to SCons
+# TODO: Meanwhile the third line will do the work
+#cplusplus = __import__('c++', globals(), locals(), [])
+#cxx_suffixes = cplusplus.CXXSuffixes
+cxx_suffixes = [".c", ".cxx", ".cpp", ".cc"]
+
+def checkMocIncluded(target, source, env):
+ moc = target[0]
+ cpp = source[0]
+ # looks like cpp.includes is cleared before the build stage :-(
+ # not really sure about the path transformations (moc.cwd? cpp.cwd?) :-/
+ path = SCons.Defaults.CScan.path(env, moc.cwd)
+ includes = SCons.Defaults.CScan(cpp, env, path)
+ if not moc in includes:
+ SCons.Warnings.warn(
+ GeneratedMocFileNotIncluded,
+ "Generated moc file '%s' is not included by '%s'" %
+ (str(moc), str(cpp)))
+
+def find_file(filename, paths, node_factory):
+ for dir in paths:
+ node = node_factory(filename, dir)
+ if node.rexists():
+ return node
+ return None
+
+class _Automoc(object):
+ """
+ Callable class, which works as an emitter for Programs, SharedLibraries and
+ StaticLibraries.
+ """
+
+ def __init__(self, objBuilderName):
+ self.objBuilderName = objBuilderName
+
+ def __call__(self, target, source, env):
+ """
+ Smart autoscan function. Gets the list of objects for the Program
+ or Lib. Adds objects and builders for the special qt files.
+ """
+ try:
+ if int(env.subst('$QT4_AUTOSCAN')) == 0:
+ return target, source
+ except ValueError:
+ pass
+ try:
+ debug = int(env.subst('$QT4_DEBUG'))
+ except ValueError:
+ debug = 0
+
+ # some shortcuts used in the scanner
+ splitext = SCons.Util.splitext
+ objBuilder = getattr(env, self.objBuilderName)
+
+ # some regular expressions:
+ # Q_OBJECT detection
+ q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]')
+ # cxx and c comment 'eater'
+ #comment = re.compile(r'(//.*)|(/\*(([^*])|(\*[^/]))*\*/)')
+ # CW: something must be wrong with the regexp. See also bug #998222
+ # CURRENTLY THERE IS NO TEST CASE FOR THAT
+
+ # The following is kind of hacky to get builders working properly (FIXME)
+ objBuilderEnv = objBuilder.env
+ objBuilder.env = env
+ mocBuilderEnv = env.Moc4.env
+ env.Moc4.env = env
+
+ # make a deep copy for the result; MocH objects will be appended
+ out_sources = source[:]
+
+ for obj in source:
+ if isinstance(obj,basestring): # big kludge!
+ print "scons: qt4: '%s' MAYBE USING AN OLD SCONS VERSION AND NOT CONVERTED TO 'File'. Discarded." % str(obj)
+ continue
+ if not obj.has_builder():
+ # binary obj file provided
+ if debug:
+ print "scons: qt: '%s' seems to be a binary. Discarded." % str(obj)
+ continue
+ cpp = obj.sources[0]
+ if not splitext(str(cpp))[1] in cxx_suffixes:
+ if debug:
+ print "scons: qt: '%s' is no cxx file. Discarded." % str(cpp)
+ # c or fortran source
+ continue
+ #cpp_contents = comment.sub('', cpp.get_contents())
+ try:
+ cpp_contents = cpp.get_contents()
+ except: continue # may be an still not generated source
+ h=None
+ for h_ext in header_extensions:
+ # try to find the header file in the corresponding source
+ # directory
+ hname = splitext(cpp.name)[0] + h_ext
+ h = find_file(hname, (cpp.get_dir(),), env.File)
+ if h:
+ if debug:
+ print "scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp))
+ #h_contents = comment.sub('', h.get_contents())
+ h_contents = h.get_contents()
+ break
+ if not h and debug:
+ print "scons: qt: no header for '%s'." % (str(cpp))
+ if h and q_object_search.search(h_contents):
+ # h file with the Q_OBJECT macro found -> add moc_cpp
+ moc_cpp = env.Moc4(h)
+ moc_o = objBuilder(moc_cpp)
+ out_sources.append(moc_o)
+ #moc_cpp.target_scanner = SCons.Defaults.CScan
+ if debug:
+ print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp))
+ if cpp and q_object_search.search(cpp_contents):
+ # cpp file with Q_OBJECT macro found -> add moc
+ # (to be included in cpp)
+ moc = env.Moc4(cpp)
+ env.Ignore(moc, moc)
+ if debug:
+ print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc))
+ #moc.source_scanner = SCons.Defaults.CScan
+ # restore the original env attributes (FIXME)
+ objBuilder.env = objBuilderEnv
+ env.Moc4.env = mocBuilderEnv
+
+ return (target, out_sources)
+
+AutomocShared = _Automoc('SharedObject')
+AutomocStatic = _Automoc('StaticObject')
+
+def _detect(env):
+ """Not really safe, but fast method to detect the QT library"""
+ try: return env['QTDIR']
+ except KeyError: pass
+
+ try: return os.environ['QTDIR']
+ except KeyError: pass
+
+ moc = env.WhereIs('moc-qt4') or env.WhereIs('moc4') or env.WhereIs('moc')
+ if moc:
+ QTDIR = os.path.dirname(os.path.dirname(moc))
+ SCons.Warnings.warn(
+ QtdirNotFound,
+ "QTDIR variable is not defined, using moc executable as a hint (QTDIR=%s)" % QTDIR)
+ return QTDIR
+
+ raise SCons.Errors.StopError(
+ QtdirNotFound,
+ "Could not detect Qt 4 installation")
+ return None
+
+def generate(env):
+ """Add Builders and construction variables for qt to an Environment."""
+
+ def locateQt4Command(env, command) :
+ try :
+ fullpath = env.backtick(
+ 'pkg-config --variable %s_location QCore'%command).strip()
+ if fullpath and os.access(fullpath, os.X_OK) :
+ return fullpath
+ except OSError: pass
+ qtdir = env.subst(env['QTDIR'])
+ suffixes = [
+ '-qt4',
+ '-qt4.exe',
+ '4',
+ '4.exe',
+ '',
+ '.exe',
+ ]
+ triedPaths = []
+ for suffix in suffixes :
+ fullpath = os.path.join(qtdir,'bin',command + suffix)
+ if os.access(fullpath, os.X_OK) :
+ return fullpath
+ triedPaths.append(fullpath)
+
+ fullpath = env.Detect([command+'-qt4', command+'4', command])
+ if not (fullpath is None) : return fullpath
+
+ raise Exception("Qt4 command '" + command + "' not found. Tried: " + ', '.join(triedPaths))
+
+ CLVar = SCons.Util.CLVar
+ Action = SCons.Action.Action
+ Builder = SCons.Builder.Builder
+ splitext = SCons.Util.splitext
+
+ env['QTDIR'] = _detect(env)
+ # TODO: 'Replace' should be 'SetDefault'
+# env.SetDefault(
+ env.Replace(
+ QTDIR = _detect(env),
+ # TODO: This is not reliable to QTDIR value changes but needed in order to support '-qt4' variants
+ QT4_MOC = locateQt4Command(env,'moc'),
+ QT4_UIC = locateQt4Command(env,'uic'),
+ QT4_RCC = locateQt4Command(env,'rcc'),
+ QT4_LUPDATE = locateQt4Command(env,'lupdate'),
+ QT4_LRELEASE = locateQt4Command(env,'lrelease'),
+
+ QT4_AUTOSCAN = 1, # Should the qt tool try to figure out, which sources are to be moc'ed?
+
+ # Some QT specific flags. I don't expect someone wants to
+ # manipulate those ...
+ QT4_UICFLAGS = CLVar(''),
+ QT4_MOCFROMHFLAGS = CLVar(''),
+ QT4_MOCFROMCXXFLAGS = CLVar('-i'),
+ QT4_QRCFLAGS = '',
+
+ # suffixes/prefixes for the headers / sources to generate
+ QT4_UISUFFIX = '.ui',
+ QT4_UICDECLPREFIX = 'ui_',
+ QT4_UICDECLSUFFIX = '.h',
+ QT4_MOCINCPREFIX = '-I',
+ QT4_MOCHPREFIX = 'moc_',
+ QT4_MOCHSUFFIX = '$CXXFILESUFFIX',
+ QT4_MOCCXXPREFIX = '',
+ QT4_MOCCXXSUFFIX = '.moc',
+ QT4_QRCSUFFIX = '.qrc',
+ QT4_QRCCXXSUFFIX = '$CXXFILESUFFIX',
+ QT4_QRCCXXPREFIX = 'qrc_',
+ QT4_MOCCPPPATH = [],
+ QT4_MOCINCFLAGS = '$( ${_concat(QT4_MOCINCPREFIX, QT4_MOCCPPPATH, INCSUFFIX, __env__, RDirs)} $)',
+
+ # Commands for the qt support ...
+ QT4_UICCOM = '$QT4_UIC $QT4_UICFLAGS -o $TARGET $SOURCE',
+ QT4_MOCFROMHCOM = '$QT4_MOC $QT4_MOCFROMHFLAGS $QT4_MOCINCFLAGS -o $TARGET $SOURCE',
+ QT4_MOCFROMCXXCOM = [
+ '$QT4_MOC $QT4_MOCFROMCXXFLAGS $QT4_MOCINCFLAGS -o $TARGET $SOURCE',
+ Action(checkMocIncluded,None)],
+ QT4_LUPDATECOM = '$QT4_LUPDATE $SOURCE -ts $TARGET',
+ QT4_LRELEASECOM = '$QT4_LRELEASE $SOURCE',
+ QT4_RCCCOM = '$QT4_RCC $QT4_QRCFLAGS $SOURCE -o $TARGET',
+ )
+
+ # Translation builder
+ tsbuilder = Builder(
+ action = SCons.Action.Action('$QT4_LUPDATECOM'), #,'$QT4_LUPDATECOMSTR'),
+ multi=1
+ )
+ env.Append( BUILDERS = { 'Ts': tsbuilder } )
+ qmbuilder = Builder(
+ action = SCons.Action.Action('$QT4_LRELEASECOM'),# , '$QT4_LRELEASECOMSTR'),
+ src_suffix = '.ts',
+ suffix = '.qm',
+ single_source = True
+ )
+ env.Append( BUILDERS = { 'Qm': qmbuilder } )
+
+ # Resource builder
+ def scanResources(node, env, path, arg):
+ # I've being careful on providing names relative to the qrc file
+ # If that was not needed that code could be simplified a lot
+ def recursiveFiles(basepath, path) :
+ result = []
+ for item in os.listdir(os.path.join(basepath, path)) :
+ itemPath = os.path.join(path, item)
+ if os.path.isdir(os.path.join(basepath, itemPath)) :
+ result += recursiveFiles(basepath, itemPath)
+ else:
+ result.append(itemPath)
+ return result
+ contents = node.get_contents()
+ includes = qrcinclude_re.findall(contents)
+ qrcpath = os.path.dirname(node.path)
+ dirs = [included for included in includes if os.path.isdir(os.path.join(qrcpath,included))]
+ # dirs need to include files recursively
+ for dir in dirs :
+ includes.remove(dir)
+ includes+=recursiveFiles(qrcpath,dir)
+ return includes
+ qrcscanner = SCons.Scanner.Scanner(name = 'qrcfile',
+ function = scanResources,
+ argument = None,
+ skeys = ['.qrc'])
+ qrcbuilder = Builder(
+ action = SCons.Action.Action('$QT4_RCCCOM', '$QT4_RCCCOMSTR'),
+ source_scanner = qrcscanner,
+ src_suffix = '$QT4_QRCSUFFIX',
+ suffix = '$QT4_QRCCXXSUFFIX',
+ prefix = '$QT4_QRCCXXPREFIX',
+ single_source = True
+ )
+ env.Append( BUILDERS = { 'Qrc': qrcbuilder } )
+
+ # Interface builder
+ uic4builder = Builder(
+ action = SCons.Action.Action('$QT4_UICCOM', '$QT4_UICCOMSTR'),
+ src_suffix='$QT4_UISUFFIX',
+ suffix='$QT4_UICDECLSUFFIX',
+ prefix='$QT4_UICDECLPREFIX',
+ single_source = True
+ #TODO: Consider the uiscanner on new scons version
+ )
+ env['BUILDERS']['Uic4'] = uic4builder
+
+ # Metaobject builder
+ mocBld = Builder(action={}, prefix={}, suffix={})
+ for h in header_extensions:
+ act = SCons.Action.Action('$QT4_MOCFROMHCOM', '$QT4_MOCFROMHCOMSTR')
+ mocBld.add_action(h, act)
+ mocBld.prefix[h] = '$QT4_MOCHPREFIX'
+ mocBld.suffix[h] = '$QT4_MOCHSUFFIX'
+ for cxx in cxx_suffixes:
+ act = SCons.Action.Action('$QT4_MOCFROMCXXCOM', '$QT4_MOCFROMCXXCOMSTR')
+ mocBld.add_action(cxx, act)
+ mocBld.prefix[cxx] = '$QT4_MOCCXXPREFIX'
+ mocBld.suffix[cxx] = '$QT4_MOCCXXSUFFIX'
+ env['BUILDERS']['Moc4'] = mocBld
+
+ # er... no idea what that was for
+ static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
+ static_obj.add_src_builder('Uic4')
+ shared_obj.add_src_builder('Uic4')
+
+ # We use the emitters of Program / StaticLibrary / SharedLibrary
+ # to scan for moc'able files
+ # We can't refer to the builders directly, we have to fetch them
+ # as Environment attributes because that sets them up to be called
+ # correctly later by our emitter.
+ env.AppendUnique(PROGEMITTER =[AutomocStatic],
+ SHLIBEMITTER=[AutomocShared],
+ LIBEMITTER =[AutomocStatic],
+ )
+
+ # TODO: Does dbusxml2cpp need an adapter
+ env.AddMethod(enable_modules, "EnableQt4Modules")
+
+def enable_modules(self, modules, debug=False, crosscompiling=False) :
+ import sys
+
+ validModules = [
+ 'QtCore',
+ 'QtGui',
+ 'QtOpenGL',
+ 'Qt3Support',
+ 'QtAssistant', # deprecated
+ 'QtAssistantClient',
+ 'QtScript',
+ 'QtDBus',
+ 'QtSql',
+ 'QtSvg',
+ # The next modules have not been tested yet so, please
+ # maybe they require additional work on non Linux platforms
+ 'QtNetwork',
+ 'QtTest',
+ 'QtXml',
+ 'QtXmlPatterns',
+ 'QtUiTools',
+ 'QtDesigner',
+ 'QtDesignerComponents',
+ 'QtWebKit',
+ 'QtHelp',
+ 'QtScript',
+ 'QtScriptTools',
+ 'QtMultimedia',
+ ]
+ pclessModules = [
+# in qt <= 4.3 designer and designerComponents are pcless, on qt4.4 they are not, so removed.
+# 'QtDesigner',
+# 'QtDesignerComponents',
+ ]
+ staticModules = [
+ 'QtUiTools',
+ ]
+ invalidModules=[]
+ for module in modules:
+ if module not in validModules :
+ invalidModules.append(module)
+ if invalidModules :
+ raise Exception("Modules %s are not Qt4 modules. Valid Qt4 modules are: %s"% (
+ str(invalidModules),str(validModules)))
+
+ moduleDefines = {
+ 'QtScript' : ['QT_SCRIPT_LIB'],
+ 'QtSvg' : ['QT_SVG_LIB'],
+ 'Qt3Support' : ['QT_QT3SUPPORT_LIB','QT3_SUPPORT'],
+ 'QtSql' : ['QT_SQL_LIB'],
+ 'QtXml' : ['QT_XML_LIB'],
+ 'QtOpenGL' : ['QT_OPENGL_LIB'],
+ 'QtGui' : ['QT_GUI_LIB'],
+ 'QtNetwork' : ['QT_NETWORK_LIB'],
+ 'QtCore' : ['QT_CORE_LIB'],
+ }
+ for module in modules :
+ try : self.AppendUnique(CPPDEFINES=moduleDefines[module])
+ except: pass
+ debugSuffix = ''
+ if sys.platform in ["linux2"] and not crosscompiling :
+ if debug : debugSuffix = '_debug'
+ for module in modules :
+ if module not in pclessModules : continue
+ self.AppendUnique(LIBS=[module+debugSuffix])
+ self.AppendUnique(LIBPATH=[os.path.join("$QTDIR","lib")])
+ self.AppendUnique(CPPPATH=[os.path.join("$QTDIR","include","qt4")])
+ self.AppendUnique(CPPPATH=[os.path.join("$QTDIR","include","qt4",module)])
+ pcmodules = [module+debugSuffix for module in modules if module not in pclessModules ]
+ if 'QtDBus' in pcmodules:
+ self.AppendUnique(CPPPATH=[os.path.join("$QTDIR","include","qt4","QtDBus")])
+ if "QtAssistant" in pcmodules:
+ self.AppendUnique(CPPPATH=[os.path.join("$QTDIR","include","qt4","QtAssistant")])
+ pcmodules.remove("QtAssistant")
+ pcmodules.append("QtAssistantClient")
+ self.ParseConfig('pkg-config %s --libs --cflags'% ' '.join(pcmodules))
+ self["QT4_MOCCPPPATH"] = self["CPPPATH"]
+ return
+ if sys.platform == "win32" or crosscompiling :
+ if crosscompiling:
+ transformedQtdir = transformToWinePath(self['QTDIR'])
+ self['QT4_MOC'] = "QTDIR=%s %s"%( transformedQtdir, self['QT4_MOC'])
+ self.AppendUnique(CPPPATH=[os.path.join("$QTDIR","include")])
+ try: modules.remove("QtDBus")
+ except: pass
+ if debug : debugSuffix = 'd'
+ if "QtAssistant" in modules:
+ self.AppendUnique(CPPPATH=[os.path.join("$QTDIR","include","QtAssistant")])
+ modules.remove("QtAssistant")
+ modules.append("QtAssistantClient")
+ self.AppendUnique(LIBS=[lib+'4'+debugSuffix for lib in modules if lib not in staticModules])
+ self.PrependUnique(LIBS=[lib+debugSuffix for lib in modules if lib in staticModules])
+ if 'QtOpenGL' in modules:
+ self.AppendUnique(LIBS=['opengl32'])
+ self.AppendUnique(CPPPATH=[ '$QTDIR/include/'])
+ self.AppendUnique(CPPPATH=[ '$QTDIR/include/'+module for module in modules])
+ if crosscompiling :
+ self["QT4_MOCCPPPATH"] = [
+ path.replace('$QTDIR', transformedQtdir)
+ for path in self['CPPPATH'] ]
+ else :
+ self["QT4_MOCCPPPATH"] = self["CPPPATH"]
+ self.AppendUnique(LIBPATH=[os.path.join('$QTDIR','lib')])
+ return
+ if sys.platform=="darwin" :
+ # TODO: Test debug version on Mac
+# self.AppendUnique(LIBPATH=[os.path.join('$QTDIR','lib')])
+# self.AppendUnique(LINKFLAGS="-F$QTDIR/lib")
+# self.AppendUnique(LINKFLAGS="-L$QTDIR/lib") #TODO clean!
+# if debug : debugSuffix = 'd'
+ for module in modules :
+ self.Append(FRAMEWORKS = module)
+ self.Append(CPPPATH = ['/Library/Frameworks/%s.framework/Versions/Current/Headers/' % module])
+# self.AppendUnique(CPPPATH=[os.path.join("$QTDIR","include")])
+# self.AppendUnique(CPPPATH=[os.path.join("$QTDIR","include",module)])
+# port qt4-mac:
+#