Skip to content

Commit 4bcfcbc

Browse files
author
valera
committed
qmenu util added
git-svn-id: https://localhost/svn/aux_repos@3 81e540ad-b34e-4874-ae36-a5c7a8be91cc
0 parents  commit 4bcfcbc

File tree

7 files changed

+871
-0
lines changed

7 files changed

+871
-0
lines changed

SConstruct

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import os
2+
import sys
3+
import qt4
4+
sys.modules['SCons.Tool.qt4'] = sys.modules['qt4']
5+
6+
platforms = ['win32-msvc', 'linux-gcc']
7+
configurations = ['release', 'debug']
8+
9+
optsCache = 'options.cache'
10+
11+
opts = Variables(optsCache)
12+
opts.Add(EnumVariable('platform', 'Target platform', platforms[0], platforms))
13+
opts.Add(EnumVariable('configuration', 'Build configuration', configurations[0], configurations))
14+
15+
env = Environment(options=opts, tools = [])
16+
17+
print opts.GenerateHelpText(env)
18+
opts.Save(optsCache, env)
19+
20+
env['root'] = os.path.abspath('.')
21+
22+
prefix = '.build.%s.%s' % (env['platform'], env['configuration'])
23+
binary = env.SConscript('binary.SConscript', exports=['env'], build_dir=prefix, duplicate=0)
24+
25+
res = env.Install('.', binary)
26+
27+
Default(res)

Src/main.cpp

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include "qmenu.h"
2+
3+
#include <iostream>
4+
#include <QApplication>
5+
#include <QTextStream>
6+
7+
int main(int argc, char** argv) {
8+
QApplication app(argc, argv);
9+
10+
const char* separator = NULL;
11+
12+
for (int i = 1; i < argc-1; ++i) {
13+
if (strcmp("-s", argv[i]) == 0) {
14+
separator = argv[i+1];
15+
}
16+
}
17+
18+
QList<QString> values;
19+
20+
while (std::cin) {
21+
std::string str;
22+
std::cin >> str;
23+
values.append(str.c_str());
24+
}
25+
26+
//QTextStream stream(stdin);
27+
/*
28+
QString line;
29+
do {
30+
line = stream.readLine();
31+
values.append(line);
32+
} while (!line.isNull());
33+
*/
34+
35+
Menu menu(500, 500, values, separator);
36+
menu.setVisible(true);
37+
38+
return app.exec();
39+
}

Src/qmenu.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "qmenu.h"

Src/qmenu.h

+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
#pragma once
2+
3+
#include <QMainWindow>
4+
#include <QListWidget>
5+
#include <QListWidgetItem>
6+
#include <QLineEdit>
7+
#include <QMap>
8+
#include <QVBoxLayout>
9+
#include <QKeyEvent>
10+
#include <QApplication>
11+
12+
class LineEdit : public QLineEdit {
13+
Q_OBJECT
14+
signals:
15+
void changed();
16+
17+
private:
18+
void keyPressEvent(QKeyEvent* event) {
19+
QLineEdit::keyPressEvent(event);
20+
emit changed();
21+
}
22+
};
23+
24+
class Menu : public QMainWindow {
25+
Q_OBJECT
26+
typedef QPair<QString, QString> QStringPair;
27+
public:
28+
Menu(int width, int height, const QList<QString>& values, const char* separator = NULL)
29+
: QMainWindow(0, Qt::Popup)
30+
{
31+
if (values.size() == 0) {
32+
QApplication::exit(0);
33+
}
34+
35+
setCentralWidget(&_containerWidget);
36+
37+
QVBoxLayout* layout = new QVBoxLayout();
38+
layout->setContentsMargins(0, 0, 0, 0);
39+
layout->addWidget(&_listWidget);
40+
layout->addWidget(&_lineEdit);
41+
_containerWidget.setLayout(layout);
42+
43+
foreach(const QString& val, values) {
44+
if (separator && val.contains(separator)) {
45+
int idx = val.indexOf(separator);
46+
_items.append(QStringPair(val.left(idx), val.right(val.size() - idx - strlen(separator))));
47+
} else {
48+
_items.append(QStringPair(val, val));
49+
}
50+
}
51+
52+
resize(width, height);
53+
54+
_listWidget.setFocusPolicy(Qt::NoFocus);
55+
_lineEdit.setFocus(Qt::OtherFocusReason);
56+
57+
_rebuildList();
58+
59+
connect(&_lineEdit, SIGNAL(changed()), this, SLOT(_rebuildList()));
60+
connect(&_lineEdit, SIGNAL(editingFinished()), this, SLOT(_done()));
61+
}
62+
63+
private slots:
64+
void _done() {
65+
if (_listWidget.count() > 0) {
66+
QListWidgetItem* item = _listWidget.currentItem();
67+
if (!item) {
68+
item = _listWidget.item(0);
69+
}
70+
printf(qPrintable(_widgetToContent[item]));
71+
}
72+
QApplication::exit(0);
73+
}
74+
75+
void _rebuildList() {
76+
if (_filter.isNull() || (_filter != _lineEdit.text())) {
77+
_filter = _lineEdit.text();
78+
_listWidget.clear();
79+
_widgetToContent.clear();
80+
81+
QList<const QStringPair*> matched;
82+
83+
foreach (const QStringPair& pair, _items) {
84+
_process(matched, pair, pair.second, &_match1);
85+
}
86+
87+
foreach (const QStringPair& pair, _items) {
88+
_process(matched, pair, pair.second, &_match2);
89+
}
90+
91+
foreach (const QStringPair& pair, _items) {
92+
_process(matched, pair, pair.first, &_match1);
93+
}
94+
95+
foreach (const QStringPair& pair, _items) {
96+
_process(matched, pair, pair.first, &_match2);
97+
}
98+
99+
if (_listWidget.count() > 0) {
100+
_listWidget.setCurrentRow(0);
101+
}
102+
}
103+
}
104+
105+
private:
106+
static bool _match1(const QString& filter, QString text) {
107+
if (filter.isEmpty()) {
108+
return true;
109+
}
110+
if (filter.toLower() == filter) {
111+
text = text.toLower();
112+
}
113+
114+
return text.contains(filter);
115+
}
116+
117+
static bool _match2(const QString& filter, QString text) {
118+
if (filter.isEmpty()) {
119+
return true;
120+
}
121+
if (filter.toLower() == filter) {
122+
text = text.toLower();
123+
}
124+
125+
int fi = 0;
126+
for (int i = 0; i < text.size(); ++i) {
127+
if (text[i] == filter[fi]) {
128+
++fi;
129+
if (fi == filter.size()) {
130+
return true;
131+
}
132+
}
133+
}
134+
135+
return false;
136+
}
137+
138+
void _process(QList<const QStringPair*>& matched, const QStringPair& pair, const QString& value, bool (*matchFn)(const QString&, QString)) {
139+
if (matched.contains(&pair)) {
140+
return;
141+
}
142+
if ((*matchFn)(_filter, value)) {
143+
matched.append(&pair);
144+
QListWidgetItem* item = new QListWidgetItem(pair.second);
145+
_widgetToContent[item] = pair.first;
146+
_listWidget.addItem(item);
147+
}
148+
}
149+
150+
private:
151+
void keyPressEvent(QKeyEvent* event) {
152+
if (event->key() == Qt::Key_Up) {
153+
_listWidget.setCurrentRow(std::max(0, _listWidget.currentRow() - 1));
154+
} else if (event->key() == Qt::Key_Down) {
155+
_listWidget.setCurrentRow(std::min(_listWidget.count(), _listWidget.currentRow() + 1));
156+
} else if (event->key() == Qt::Key_Escape) {
157+
QApplication::exit(0);
158+
}
159+
QMainWindow::keyPressEvent(event);
160+
}
161+
162+
QWidget _containerWidget;
163+
QString _filter;
164+
QListWidget _listWidget;
165+
LineEdit _lineEdit;
166+
QList<QStringPair> _items;
167+
QMap<QListWidgetItem*, QString> _widgetToContent;
168+
};

binary.SConscript

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import binary
2+
3+
Import('env')
4+
5+
name = 'qmenu'
6+
7+
libs = {
8+
'win32-msvc' : [],
9+
'linux-gcc' : [],
10+
}
11+
libpaths = {
12+
'win32-msvc' : [],
13+
'linux-gcc' : [],
14+
}
15+
cpppaths = ['Src']
16+
srcpaths = ['Src']
17+
18+
platform = env['platform']
19+
20+
result = binary.createBinary(
21+
env,
22+
name,
23+
['QtCore', 'QtNetwork', 'QtGui', 'QtOpenGL'],
24+
libs[platform],
25+
cpppaths,
26+
libpaths[platform],
27+
srcpaths,
28+
)
29+
30+
Return('result')
31+

binary.py

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import os
2+
import os.path
3+
4+
#def _relpath(path, root):
5+
# path = os.path.normpath(os.path.abspath(path))
6+
# root = os.path.normpath(os.path.abspath(root))
7+
# assert path.startswith(root)
8+
# return path[len(root) + 1:]
9+
#os.path.relpath = _relpath
10+
11+
def gatherSources(dirs):
12+
res = []
13+
for d in dirs:
14+
for dirname, dirnames, filenames in os.walk(d):
15+
for filename in filenames:
16+
fpath = os.path.join(dirname, filename)
17+
if fpath.endswith('.cpp') or fpath.endswith('.c'):
18+
res.append(fpath)
19+
return res
20+
21+
def configureCompiler(env, platform, configuration):
22+
tools = {
23+
'linux-gcc' : ['qt4', 'g++', 'ar', 'gnulink'],
24+
'win32-msvc' : ['qt4', 'msvc', 'mslink'],
25+
}
26+
flags = {
27+
'linux-gcc' : {
28+
'debug' : ['-Wall', '-Werror', '-g'],
29+
'release' : ['-Wall', '-Werror'],
30+
},
31+
'win32-msvc' : {
32+
'debug' : ['/Zi'],
33+
'release' : [],
34+
},
35+
}
36+
defines = {
37+
'linux-gcc' : ['TARGET_PLATFORM_LINUX', 'TARGET_PLATFORM_LINUX_GCC'],
38+
'win32-msvc' : ['TARGET_PLATFORM_WINDOWS', 'TARGET_PLATFORM_WIN32_MSVC'],
39+
}
40+
commonDefines = ['PUGIXML_NO_EXCEPTIONS']
41+
targetArch = {
42+
'linux-gcc' : None,
43+
'win32-msvc' : 'x86',
44+
'win64-msvc' : 'x86_64',
45+
}
46+
47+
if targetArch[platform]:
48+
env['TARGET_ARCH'] = targetArch[platform]
49+
for tool in tools[platform]:
50+
env.Tool(tool)
51+
env.Append(CCFLAGS = flags[platform][configuration])
52+
env.Append(CPPDEFINES = defines[platform] + commonDefines)
53+
54+
55+
def createBinary(env, name, qtLibs, libs, cppPaths, libPaths, sourceDirs):
56+
env = env.Clone()
57+
58+
configureCompiler(env, env['platform'], env['configuration'])
59+
env.EnableQt4Modules(qtLibs, debug=False, crosscompiling=False)
60+
61+
env.Append(CPPPATH=cppPaths)
62+
env.Append(LIBPATH=libPaths)
63+
64+
env.AppendUnique(LIBS=libs)
65+
66+
sourceDirs = map(lambda x : os.path.join(env['root'], x), sourceDirs)
67+
68+
sources = gatherSources(sourceDirs)
69+
70+
sources = map(lambda x : os.path.relpath(x, env['root']), sources)
71+
72+
objects = env.Object(sources)
73+
74+
if env['platform'] == 'win32-msvc':
75+
env['PDB'] = '${TARGET}.pdb'
76+
name += '.exe'
77+
78+
return env.Program(name, objects)
79+

0 commit comments

Comments
 (0)