git-svn-id: svn://db.shs.com.ru/libs@586 a8b55f48-bf90-11e4-a774-851b48703e85

This commit is contained in:
2019-09-02 14:08:38 +00:00
parent f862381b68
commit 3d06d2095e
929 changed files with 66799 additions and 0 deletions

View File

@@ -0,0 +1 @@
qad_project(application "Gui;Widgets" "qad_widgets")

View File

@@ -0,0 +1,96 @@
#include "edockwidget.h"
#include "qad_types.h"
#include <QEvent>
#include <QStyle>
void EDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features) {
btn_dock->setVisible(features.testFlag(DockWidgetFloatable));
btn_hide->setVisible(features.testFlag(DockWidgetClosable));
QDockWidget::setFeatures(features);
}
void EDockWidget::setWindowTitle(const QString & title) {
lbl_title->setText(title);
QDockWidget::setWindowTitle(title);
}
void EDockWidget::setWindowIcon(const QIcon & icon) {
//#ifndef Q_OS_MACOS
lbl_icon->setPixmap(icon.pixmap(QSize(256, 256)));
QDockWidget::setWindowIcon(icon);
if (!icon.isNull()) {
lbl_icon->setScaledContents(true);
lbl_icon->setFixedSize(preferredIconSize(1.5, this));
}
//#endif
}
bool EDockWidget::event(QEvent * e) {
if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish) {
updateStyle();
}
return QDockWidget::event(e);
}
void EDockWidget::init() {
header = new QFrame();
header->setFrameShape(QFrame::StyledPanel);
QBoxLayout * lay = new QBoxLayout(features().testFlag(QDockWidget::DockWidgetVerticalTitleBar) ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight);
lay->setContentsMargins(2, 2, 2, 2);
lay->setSpacing(2);
lbl_icon = new QLabel();
//#ifndef Q_OS_MACOS
QIcon wi = windowIcon();
if (!wi.isNull()) {
lbl_icon->setPixmap(wi.pixmap(QSize(256,256)));
/*#if QT_VERSION >= 0x500000
if (lbl_icon->pixmap())
const_cast<QPixmap*>(lbl_icon->pixmap())->setDevicePixelRatio(1.);
#endif*/
//qDebug() << windowTitle() << wi.pixmap(QSize(256,256)).size();
lbl_icon->setScaledContents(true);
}
lbl_icon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
//#endif
lbl_title = new QLabel(windowTitle());
lbl_title->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
btn_dock = new QToolButton();
//btn_dock->setIconSize(QSize(16, 16));
btn_dock->setAutoRaise(true);
btn_dock->setFocusPolicy(Qt::NoFocus);
btn_dock->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
btn_hide = new QToolButton();
//btn_hide->setIconSize(QSize(16, 16));
btn_hide->setAutoRaise(true);
btn_hide->setFocusPolicy(Qt::NoFocus);
btn_hide->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
connect(btn_dock, SIGNAL(clicked(bool)), this, SLOT(dockClicked()));
connect(btn_hide, SIGNAL(clicked(bool)), this, SLOT(hide()));
lay->addWidget(lbl_icon);
lay->addWidget(lbl_title);
lay->addWidget(btn_dock);
lay->addWidget(btn_hide);
header->setLayout(lay);
updateStyle();
setTitleBarWidget(header);
}
void EDockWidget::updateStyle() {
QSize icon_size = preferredIconSize(0.75, this);
int bm = 2 * style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, 0, this);
QSize btn_size = icon_size;
btn_size += QSize(bm, bm);
btn_dock->setIcon(style()->standardIcon(QStyle::SP_TitleBarNormalButton));
btn_dock->setIconSize(icon_size);
btn_dock->setFixedSize(btn_size);
btn_hide->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
btn_hide->setIconSize(icon_size);
btn_hide->setFixedSize(btn_size);
lbl_icon->setFixedSize(preferredIconSize(1.5, this));
}

View File

@@ -0,0 +1,39 @@
#ifndef EDOCKWIDGET_H
#define EDOCKWIDGET_H
#include <QDockWidget>
#include <QLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QIcon>
#include <QToolButton>
#include <QDebug>
class EDockWidget: public QDockWidget
{
Q_OBJECT
public:
explicit EDockWidget(const QString & title, QWidget * parent = 0, Qt::WindowFlags flags = 0): QDockWidget(title, parent, flags) {init();}
explicit EDockWidget(QWidget * parent = 0, Qt::WindowFlags flags = 0): QDockWidget(parent, flags) {init();}
~EDockWidget() {delete btn_hide; delete btn_dock; delete lbl_title; delete lbl_icon; delete header;}
void setFeatures(QDockWidget::DockWidgetFeatures features);
void setWindowTitle(const QString & title);
void setWindowIcon(const QIcon & icon);
private:
bool event(QEvent * e);
void init();
void updateStyle();
QFrame * header;
QLabel * lbl_title, * lbl_icon;
QToolButton * btn_hide, * btn_dock;
private slots:
void dockClicked() {setFloating(!isFloating());}
};
#endif // EDOCKWIDGET_H

View File

@@ -0,0 +1,423 @@
#include "emainwindow.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QMenu>
#include <QLabel>
EMainWindow::EMainWindow(QWidget * parent): QMainWindow(parent), action_show_all_tools(this), action_hide_all_tools(this),
action_show_all_docks(this), action_hide_all_docks(this), first_show(true) {
tid = 0;
menu_recent = 0;
action_clear_recent = new QAction(QIcon(":/icons/edit-clear.png"), tr("Clear recent list"), this);
connect(action_clear_recent, SIGNAL(triggered()), this, SLOT(clearRecent()));
qRegisterMetaType<Qt::DockWidgetArea>("Qt::DockWidgetArea");
action_show_all_tools.setText(trUtf8("Show all"));
action_show_all_docks.setText(trUtf8("Show all"));
action_hide_all_tools.setText(trUtf8("Hide all"));
action_hide_all_docks.setText(trUtf8("Hide all"));
action_show_all_tools.setIcon(QIcon(":/icons/layer-visible-on.png"));
action_show_all_docks.setIcon(QIcon(":/icons/layer-visible-on.png"));
action_hide_all_tools.setIcon(QIcon(":/icons/layer-visible-off.png"));
action_hide_all_docks.setIcon(QIcon(":/icons/layer-visible-off.png"));
max_recent = 8;
setChanged(false);
initMenus();
initSession();
tid = startTimer(200); // bad timer, too much overload
}
EMainWindow::~EMainWindow() {
if (tid > 0) killTimer(tid);
tid = 0;
saveSession();
}
void EMainWindow::setRecentFiles(const QStringList & rl) {
clearRecent();
for (int i = rl.size() - 1; i >= 0; --i)
addToRecent(rl[i]);
}
QStringList EMainWindow::recentFiles() const {
QStringList ret;
foreach (QAction * a, actions_recent)
ret << a->data().toString();
return ret;
}
void EMainWindow::setRecentMenu(QMenu * m) {
menu_recent = m;
prepareRecent();
}
void EMainWindow::showEvent(QShowEvent * e) {
QWidget::showEvent(e);
initMenus();
if (!first_show) return;
first_show = false;
QList<QDockWidget * > docks(findChildren<QDockWidget * >());
foreach (QDockWidget * d, docks) {
connect(d, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(changedDock()));
connect(d, SIGNAL(topLevelChanged(bool)), this, SLOT(changedDock()));
}
changedDock();
}
void EMainWindow::closeEvent(QCloseEvent * e) {
if (!checkSave()) e->ignore();
}
bool EMainWindow::eventFilter(QObject * o, QEvent * e) {
//qDebug() << o << e;
if (tbars.contains((QTabBar*)o) && e->type() == QEvent::MouseButtonDblClick) {
int tab = ((QTabBar*)o)->tabAt(((QMouseEvent * )e)->pos());
if (tab >= 0) {
QDockWidget * dock = (QDockWidget * )(((QTabBar*)o)->tabData(tab).toULongLong());
if (dock != 0) {
dock->setFloating(true);
}
}
}
if (e->type() == QEvent::Show || e->type() == QEvent::Hide || e->type() == QEvent::ChildAdded || e->type() == QEvent::ChildRemoved || e->type() == QEvent::MouseButtonPress) {
if (tbars.contains((QTabBar*)o) || tdocks.contains((QDockWidget*)o)) {
if (e->type() == QEvent::MouseButtonPress) {
if (((QMouseEvent*)e)->button() == Qt::RightButton) {
bool popup = tbars.contains((QTabBar*)o);
if (tdocks.contains((QDockWidget*)o))
popup = popup || ((QDockWidget*)o)->titleBarWidget()->geometry().contains(((QMouseEvent*)e)->pos());
if (popup) {
createPopupMenu()->popup(((QMouseEvent*)e)->globalPos());
return true;
}
}
}
if (e->type() == QEvent::Show || e->type() == QEvent::Hide /*|| e->type() == QEvent::ChildAdded || e->type() == QEvent::ChildRemoved*/) {
//qDebug() << "filter";
//QMetaObject::invokeMethod(this, "changedDock", Qt::QueuedConnection);
changedDock();
}
}
}
return QMainWindow::eventFilter(o, e);
}
void EMainWindow::timerEvent(QTimerEvent * e) {
if (e->timerId() == tid) {
changedDock();
return;
}
QMainWindow::timerEvent(e);
}
QMenu * EMainWindow::createPopupMenu() {
QMenu * menuPopup = new QMenu;
QWidgetAction * wa;
QLabel * lbl;
QAction * a;
QFont f;
f.setBold(true);
// Toolbars
QList<QToolBar * > tools = findChildren<QToolBar * >();
if (!tools.isEmpty()) {
wa = new QWidgetAction(menuPopup);
lbl = new QLabel();
lbl->setFrameShape(QFrame::StyledPanel);
lbl->setFrameShadow(QFrame::Sunken);
lbl->setText(trUtf8("Toolbars"));
lbl->setFont(f);
lbl->setAlignment(Qt::AlignCenter);
wa->setDefaultWidget(lbl);
menuPopup->addAction(wa);
foreach (QToolBar * i, tools) {
if (i->property("ribbon").toBool()) continue;
a = new QAction(i->windowTitle(), menuPopup);
a->setCheckable(true);
a->setChecked(!i->isHidden());
a->setIcon(i->windowIcon());
connect(a, SIGNAL(toggled(bool)), i, SLOT(setVisible(bool)));
menuPopup->addAction(a);
}
menuPopup->addSeparator();
menuPopup->addAction(&action_show_all_tools);
menuPopup->addAction(&action_hide_all_tools);
}
// Docks
QList<QDockWidget * > docks = findChildren<QDockWidget * >();
if (!docks.isEmpty()) {
wa = new QWidgetAction(menuPopup);
lbl = new QLabel();
lbl->setFrameShape(QFrame::StyledPanel);
lbl->setFrameShadow(QFrame::Sunken);
lbl->setText(trUtf8("Docks"));
lbl->setFont(f);
lbl->setAlignment(Qt::AlignCenter);
wa->setDefaultWidget(lbl);
menuPopup->addAction(wa);
foreach (QDockWidget * i, docks) {
if (i->property("ribbon").toBool()) continue;
a = new QAction(i->windowTitle(), menuPopup);
a->setCheckable(true);
a->setChecked(!i->isHidden());
a->setIcon(i->windowIcon());
connect(a, SIGNAL(toggled(bool)), i, SLOT(setVisible(bool)));
menuPopup->addAction(a);
}
menuPopup->addSeparator();
menuPopup->addAction(&action_show_all_docks);
menuPopup->addAction(&action_hide_all_docks);
}
return menuPopup;
}
void EMainWindow::addToRecent(const QString & path) {
if (path.isEmpty()) return;
QFileInfo fi(path);
QString fp = fi.absoluteFilePath();
bool insert = true;
for (int i = 0; i < actions_recent.size(); ++i)
if (actions_recent[i]->data().toString() == fp) {
actions_recent.push_front(actions_recent.takeAt(i));
insert = false;
prepareRecent();
break;
}
if (!insert) return;
QAction * a = new QAction(this);
a->setData(fp);
connect(a, SIGNAL(triggered()), this, SLOT(recentTriggered()));
actions_recent.push_front(a);
while (actions_recent.size() > max_recent)
delete actions_recent.takeLast();
prepareRecent();
}
void EMainWindow::prepareRecent() {
for (int i = 0; i < actions_recent.size(); ++i) {
QAction * a = actions_recent[i];
a->setText(QString("&%1 - %2").arg(i + 1).arg(a->data().toString()));
}
if (!menu_recent) return;
menu_recent->clear();
menu_recent->addActions(actions_recent);
menu_recent->addSeparator();
menu_recent->addAction(action_clear_recent);
}
void EMainWindow::initMenus() {
action_show_all_tools.disconnect();
action_hide_all_tools.disconnect();
action_show_all_docks.disconnect();
action_hide_all_docks.disconnect();
QList<QToolBar * > tools = findChildren<QToolBar * >();
foreach (QToolBar * i, tools) {
if (i->property("ribbon").toBool()) continue;
i->toggleViewAction()->setIcon(i->windowIcon());
connect(&action_show_all_tools, SIGNAL(triggered(bool)), i, SLOT(show()));
connect(&action_hide_all_tools, SIGNAL(triggered(bool)), i, SLOT(hide()));
}
QList<QDockWidget * > docks = findChildren<QDockWidget * >();
foreach (QDockWidget * i, docks) {
if (i->property("ribbon").toBool()) continue;
i->toggleViewAction()->setIcon(i->windowIcon());
connect(&action_show_all_docks, SIGNAL(triggered(bool)), i, SLOT(show()));
connect(&action_hide_all_docks, SIGNAL(triggered(bool)), i, SLOT(hide()));
}
QList<QAction * > actions = findChildren<QAction * >();
foreach (QAction * i, actions)
i->setIconVisibleInMenu(true);
addActions(actions);
}
void EMainWindow::initSession() {
connect(&session, SIGNAL(loading(QPIConfig & )), this, SLOT(sessionLoading(QPIConfig & )));
connect(&session, SIGNAL(saving(QPIConfig & )), this, SLOT(sessionSaving(QPIConfig & )));
}
void EMainWindow::saveSession() {
session.save();
}
void EMainWindow::loadSession() {
session.load();
}
bool EMainWindow::checkSave() {
if (!isWindowModified()) return true;
return saveFile(true);
}
void EMainWindow::changedDock() {
if (isHidden()) return;
QList<QTabBar * > tabs(findChildren<QTabBar * >());
QList<QDockWidget * > docks = findChildren<QDockWidget * >();
// QSet<QDockWidget * > docks_tabs;
QDockWidget * dock;
// qDebug() << "### change";
foreach (QTabBar * t, tabs) {
if (!t->objectName().isEmpty() || t->isHidden()) continue;
if (!tbars.contains(t)) {
tbars << t;
connect(t, SIGNAL(tabCloseRequested(int)), this, SLOT(closeDock(int)));
t->installEventFilter(this);
#ifndef Q_OS_MACOS
t->setIconSize(dockTabsIconSize());
#endif
t->setTabsClosable(true);
}
// qDebug() << "tab" << t << t->count();
for (int i = 0; i < t->count(); ++i) {
dock = (QDockWidget * )t->tabData(i).toULongLong();
//qDebug() << i << t->tabData(i);
if (!docks.contains(dock)) continue;
#ifndef Q_OS_MACOS
t->setIconSize(dockTabsIconSize());
#endif
t->setTabIcon(i, dock->windowIcon());
// docks_tabs << dock;
}
}
foreach (QDockWidget * d, docks) {
if (d->titleBarWidget() == 0) continue;
QWidget * ctb = d->titleBarWidget();
if (!d->property("__titleWidget").isValid()) {
d->setProperty("__titleWidget", qulonglong(ctb));
QWidget * ntb = new QWidget();
int m = style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin);
ntb->setLayout(new QBoxLayout(QBoxLayout::BottomToTop));
ntb->layout()->setContentsMargins(m, m, 0, 0);
d->setProperty("__titleEmptyWidget", qulonglong(ntb));
}
if (!tdocks.contains(d)) {
tdocks << d;
// qDebug() << "connect" << d;
// connect(d, SIGNAL(destroyed(QObject*)), this, SLOT(changedDockClose(QObject*)), Qt::UniqueConnection);
d->installEventFilter(this);
}
//d->titleBarWidget()->setHidden(docks_tabs.contains(d));
if (tabifiedDockWidgets(d).isEmpty()) {
if (d->titleBarWidget() != (QWidget * )(d->property("__titleWidget").toULongLong()))
d->setTitleBarWidget((QWidget * )(d->property("__titleWidget").toULongLong()));
} else {
if (d->titleBarWidget() != (QWidget * )(d->property("__titleEmptyWidget").toULongLong())) {
d->setTitleBarWidget((QWidget * )(d->property("__titleEmptyWidget").toULongLong()));
d->layout()->setContentsMargins(0, 20, 0, 0);
}
}
}
}
//void EMainWindow::changedDockClose(QObject * dock) {
// qDebug() << "changedDockClose" << dock;
// if (!dock) return;
// foreach (QTabBar * t, tbars) {
// for (int i = 0; i < t->count(); ++i)
// if (t->tabData(i).toULongLong() == (qulonglong)dock) {
// t->removeTab(i);
// break;
// }
// }
//}
void EMainWindow::closeDock(int index) {
QDockWidget * dock = (QDockWidget * )((QTabBar*)sender())->tabData(index).toULongLong();
if (dock == 0) return;
dock->close();
}
void EMainWindow::recentTriggered() {
QAction * a = qobject_cast<QAction * >(sender());
if (!a) return;
QString path = a->data().toString();
if (path.isEmpty()) return;
if (!checkSave()) return;
if (load(path))
addToRecent(path);
}
void EMainWindow::setMaxRecentItems(int mr) {
max_recent = qMax(0, mr);
for (int i = actions_recent.size() - 1; i >= mr; --i)
delete actions_recent.takeLast();
}
void EMainWindow::newFile() {
if (!checkSave()) return;
reset(true);
setWindowModified(false);
}
void EMainWindow::openFile() {
if (!checkSave()) return;
QString ret = QFileDialog::getOpenFileName(this, trUtf8("Select file to open"), file_name, loadFilter());
if (ret.isEmpty()) return;
if (load(ret))
addToRecent(ret);
}
void EMainWindow::openFiles() {
if (!checkSave()) return;
QStringList ret = QFileDialog::getOpenFileNames(this, trUtf8("Select files to open"), file_name, loadFilter());
foreach (QString s, ret) {
if (load(s))
addToRecent(s);
}
}
bool EMainWindow::saveFile(bool ask) {
if (ask) {
int ret = QMessageBox::question(this, windowTitle(), trUtf8("Save changes%1?").arg(!file_name.isEmpty() ? (trUtf8(" in") + " \"" + file_name + "\"") : ""), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save);
if (ret == QMessageBox::Cancel) return false;
if (ret == QMessageBox::Save) return saveFile();
return true;
}
if (file_name.isEmpty()) return saveAsFile();
if (save(file_name))
addToRecent(file_name);
return true;
}
bool EMainWindow::saveAsFile() {
QString ret = QFileDialog::getSaveFileName(this, trUtf8("Select file to save"), file_name, saveFilter());
if (ret.isEmpty()) return false;
if (save(ret))
addToRecent(ret);
return true;
}
void EMainWindow::clearRecent() {
qDeleteAll(actions_recent);
actions_recent.clear();
prepareRecent();
}

View File

@@ -0,0 +1,127 @@
#ifndef EMAINWINDOW_H
#define EMAINWINDOW_H
#include <QTranslator>
#include <QUrl>
#include <QDesktopWidget>
#include <QInputDialog>
#include <QClipboard>
#include <QRadioButton>
#include <QThread>
#include <QColorDialog>
#include <QTime>
#include <QSplitter>
#include "session_manager.h"
#include "ribbon.h"
class UAction: public QAction {
Q_OBJECT
public:
UAction(int ind,const QString & text, QObject * parent): QAction(text, parent) {
index = ind;
connect(this, SIGNAL(triggered()), this, SLOT(triggered()));
connect(this, SIGNAL(toggled(bool)), this, SLOT(toggled(bool)));
connect(this, SIGNAL(hovered()), this, SLOT(hovered()));
}
UAction(int ind, const QIcon & icon, const QString & text, QObject * parent): QAction(icon, text, parent) {
index = ind;
connect(this, SIGNAL(triggered()), this, SLOT(triggered()));
connect(this, SIGNAL(toggled(bool)), this, SLOT(toggled(bool)));
connect(this, SIGNAL(hovered()), this, SLOT(hovered()));
}
public slots:
void show() {setVisible(true);}
void hide() {setVisible(false);}
void setCheckedTrue() {setChecked(true);}
void setCheckedFalse() {setChecked(false);}
private:
int index;
private slots:
void triggered() {emit itriggered(this, index);}
void toggled(bool t) {emit itoggled(t, this, index);}
void hovered() {emit ihovered(this);}
signals:
void itriggered(QAction *, int);
void itoggled(bool, QAction *, int);
void ihovered(QAction * action);
};
class EMainWindow: public QMainWindow
{
Q_OBJECT
Q_PROPERTY(int maxRecentItems READ maxRecentItems WRITE setMaxRecentItems)
public:
EMainWindow(QWidget * parent = 0);
~EMainWindow();
virtual void reset(bool full = false) {}
virtual bool load(const QString & path) {return true;}
virtual bool save(const QString & path) {return true;}
void addSeparator() {}
void setRecentFiles(const QStringList & rl);
QStringList recentFiles() const;
void setRecentMenu(QMenu * m);
int maxRecentItems() const {return max_recent;}
protected:
// Qt`s overloaded
void showEvent(QShowEvent * );
void closeEvent(QCloseEvent * );
bool eventFilter(QObject * o, QEvent * e);
void timerEvent(QTimerEvent * e);
QMenu * createPopupMenu();
void addToRecent(const QString & path);
void prepareRecent();
void init(const QString & config) {session.setFile(config); initMenus(); initSession(); loadSession();} // unusable
void saveSession();
void loadSession();
virtual void savingSession(QPIConfig & conf) {}
virtual void loadingSession(QPIConfig & conf) {}
virtual QSize dockTabsIconSize() const {return iconSize();}
virtual QString loadFilter() {return "All files(*)";}
virtual QString saveFilter() {return "All files(*)";}
bool checkSave();
void setChanged(bool yes = true) {isChanged = yes; setWindowModified(yes);}
void initMenus();
void initSession();
QAction action_show_all_tools, action_hide_all_tools, action_show_all_docks, action_hide_all_docks;
QString file_name;
QList<QTabBar * > tbars;
QList<QDockWidget * > tdocks;
QList<QAction * > actions_recent;
QAction * action_clear_recent;
QMenu * menu_recent;
SessionManager session;
bool isChanged, first_show;
int tid, max_recent;
private slots:
void changedDock();
void sessionLoading(QPIConfig & conf) {loadingSession(conf);}
void sessionSaving(QPIConfig & conf) {savingSession(conf);}
// void changedDockClose(QObject * dock);
void closeDock(int index);
void recentTriggered();
public slots:
void setMaxRecentItems(int mr);
void changed() {setChanged(true);}
void newFile();
void openFile();
void openFiles();
bool saveFile(bool ask = false);
bool saveAsFile();
void clearRecent();
signals:
};
#endif // MAINWINDOW_H

View File

@@ -0,0 +1,104 @@
#include "etabwidget.h"
ETabWidget::ETabWidget(QWidget* parent): QTabWidget(parent) {
tabBar()->setMouseTracking(true);
tabBar()->installEventFilter(this);
}
void ETabWidget::retranslate() {
for (int i = 0; i < buttons.size(); ++i)
buttons[i].toolTip = QApplication::translate("MainWindow", buttons[i].srcToolTip.toUtf8(), 0/*, QCoreApplication::UnicodeUTF8*/);
QList<QToolButton * > bl = findChildren<QToolButton * >();
foreach (QToolButton * i, bl)
i->setToolTip(QApplication::translate("MainWindow", i->property("sourceToolTip").toString().toUtf8(), 0/*, QCoreApplication::UnicodeUTF8*/));
}
int ETabWidget::addTab(QWidget * page, const QIcon & icon, const QString & label) {
int ret = QTabWidget::addTab(page, icon, label);
QWidget * w = new QWidget();
w->setLayout(new QBoxLayout(QBoxLayout::RightToLeft));
w->layout()->setContentsMargins(0, 0, 0, 0);
w->layout()->setSpacing(2);
QToolButton * b;
foreach (const TabButton & i, buttons) {
b = new QToolButton();
b->setToolTip(i.toolTip);
b->setIconSize(QSize(16, 16));
b->setIcon(i.icon);
//b->setFlat(true);
b->setProperty("sourceToolTip", i.toolTip);
b->setProperty("buttonRole", i.role);
connect(b, SIGNAL(clicked(bool)), this, SLOT(buttonClicked()));
w->layout()->addWidget(b);
b->setVisible(i.visible);
}
tabBar()->setTabButton(ret, QTabBar::RightSide, w);
return ret;
}
void ETabWidget::setButtonVisible(int role, bool yes) {
QList<QToolButton * > bl = findChildren<QToolButton * >();
foreach (QToolButton * i, bl)
if (i->property("buttonRole").toInt() == role)
i->setVisible(yes);
QWidget * w;
for (int i = 0; i < buttons.size(); ++i) {
if (buttons[i].role == role)
buttons[i].visible = yes;
w = tabBar()->tabButton(i, QTabBar::RightSide);
if (w != 0) w->adjustSize();
}
tabBar()->adjustSize();
}
/*
void ETabWidget::removeTab(int index) {
tbs.removeAll(qobject_cast<QToolButton * >(tabBar()->tabButton(index, QTabBar::RightSide)->layout()->itemAt(1)->widget()));
tbs.removeAll(qobject_cast<QToolButton * >(tabBar()->tabButton(index, QTabBar::RightSide)->layout()->itemAt(0)->widget()));
QTabWidget::removeTab(index);
}
*/
bool ETabWidget::eventFilter(QObject * o, QEvent * e) {
static int prev = -1;
if (e->type() == QEvent::MouseMove) {
QTabBar * t = qobject_cast<QTabBar * >(o);
if (t == 0) return QTabWidget::eventFilter(o, e);
for (int i = 0; i < count(); ++i)
if (t->tabRect(i).contains(((QMouseEvent * )e)->pos())) {
if (i != prev) {
prev = i;
emit tabHovered(i);
}
return QTabWidget::eventFilter(o, e);
}
if (-1 != prev) {
prev = -1;
emit tabHovered(-1);
}
}
if (e->type() == QEvent::Leave) {
if (-1 != prev) {
prev = -1;
emit tabHovered(-1);
}
}
return QTabWidget::eventFilter(o, e);
}
void ETabWidget::buttonClicked() {
QToolButton * s = qobject_cast<QToolButton * >(sender());
if (s == 0) return;
QWidget * pw = s->parentWidget();
if (pw == 0) return;
for (int i = 0; i < count(); ++i)
if (tabBar()->tabButton(i, QTabBar::RightSide) == pw) {
emit tabButtonClicked(i, s->property("buttonRole").toInt());
return;
}
}

View File

@@ -0,0 +1,54 @@
#ifndef ETABWIDGET_H
#define ETABWIDGET_H
#include <QTabWidget>
#include <QDebug>
#include <QTabBar>
#include <QMouseEvent>
#include <QEvent>
#include <QToolButton>
#include <QPushButton>
#include <QLayout>
#include <QHBoxLayout>
#include <QApplication>
class ETabWidget: public QTabWidget
{
Q_OBJECT
public:
explicit ETabWidget(QWidget * parent = 0);
void retranslate();
void addTabButton(int role, const QIcon & icon, const QString & toolTip = QString()) {buttons << TabButton(role, icon, toolTip);}
int addTab(QWidget * page, const QIcon & icon, const QString & label);
int addTab(QWidget * page, const QString & label) {return addTab(page, QIcon(), label);}
void setButtonVisible(int role, bool yes);
private:
bool eventFilter(QObject * o, QEvent * e);
void tabInserted(int) {emit countChanged();}
void tabRemoved(int) {emit countChanged();}
struct TabButton {
TabButton(int r, const QIcon & i, const QString & t) {role = r; icon = i; visible = true; srcToolTip = t; toolTip = QApplication::translate("MainWindow", t.toUtf8(), 0/*, QCoreApplication::UnicodeUTF8*/);}
int role;
bool visible;
QIcon icon;
QString srcToolTip;
QString toolTip;
};
QList<TabButton> buttons;
private slots:
void buttonClicked();
signals:
void countChanged();
void tabHovered(int tab);
void tabButtonClicked(int tab, int role);
};
#endif // ETABWIDGET_H

View File

@@ -0,0 +1,161 @@
#include "historyview.h"
HistoryView::HistoryView(QWidget* parent): QListWidget(parent) {
setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
setSelectionMode(QAbstractItemView::MultiSelection);
setEditTriggers(NoEditTriggers);
active_ = true;
duplicates_ = false;
index = 0;
setLimit(32);
setHistoryColor(palette().color(QPalette::Highlight));
connect(this, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(itemClicked(QListWidgetItem*)));
connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged()));
registerAction(-1, tr("History cleared"), QImage(":/icons/clear-history.png"));
}
HistoryView::~HistoryView() {
}
QByteArray HistoryView::current() const {
QListWidgetItem * ci = currentItem();
if (!ci) return QByteArray();
int i = row(ci);
if (i < 0 || i >= history_.size()) return QByteArray();
return history_[i].command;
}
void HistoryView::addEntry(int action, int count_, const QString & suffix) {
if (!active_) return;
QByteArray ba;
emit commandRequest(ba);
if (!duplicates_)
if (current() == ba)
return;
int cnt = count();
for (int i = index; i < cnt; ++i)
if (i >= 0) delete takeItem(index);
QListWidgetItem * li = new QListWidgetItem(actions_.value(action).icon, actionText(action, count_) + suffix);
blockSignals(true);
addItem(li);
setCurrentItem(li);
index = count();
history_.resize(index);
history_.back() = Entry(action, ba);
checkLimit();
scrollToItem(item(index - 1));
for (int i = 0; i < index; ++i)
item(i)->setSelected(true);
blockSignals(false);
emit changed();
emit redoAvailable(false);
emit undoAvailable((index > 1));
emit clearAvailable(history_.count() > 1);
}
void HistoryView::registerAction(int action, const QString & text, const QImage & icon) {
actions_[action] = HistoryView::Action(action, text, icon);
}
QString HistoryView::actionText(int action, int count_) {
return QString(actions_.value(action).text).replace("%count", QString::number(count_));
}
void HistoryView::checkLimit() {
if (count() < limit_ + 1) return;
int c = count() - limit_;
for (int i = 0; i < c; ++i) {
if (i >= index - 1) {
if (count() < 2) break;
delete takeItem(1);
history_.remove(1);
} else {
if (count() < 1) break;
delete takeItem(0);
history_.pop_front();
index--;
}
}
if (index < 1) index = 1;
if (index > count()) index = count();
}
void HistoryView::itemClicked(QListWidgetItem * item) {
if (!active_) return;
if (index == row(item) + 1) return;
index = row(item) + 1;
//qDebug() << actions[index - 1].command;
emit commandExecute(history_[index - 1].command);
emit changed();
itemSelectionChanged();
}
void HistoryView::itemSelectionChanged() {
if (!active_) return;
if (index < 1) index = 1;
//qDebug() << "changed" << count();
blockSignals(true);
setCurrentItem(item(index - 1));
for (int i = 0; i < index; ++i)
item(i)->setSelected(true);
for (int i = index; i < count(); ++i)
item(i)->setSelected(false);
blockSignals(false);
emit redoAvailable(index < count());
emit undoAvailable((index > 1));
}
void HistoryView::setLimit(int l) {
limit_ = l;
checkLimit();
emit redoAvailable(index < count());
emit undoAvailable((index > 1));
}
void HistoryView::setHistoryColor(const QColor & c) {
color_ = c;
QPalette pal(palette());
pal.setColor(QPalette::Highlight, color_);
pal.setColor(QPalette::HighlightedText, pal.color(QPalette::Text));
setPalette(pal);
}
void HistoryView::clear(bool silent) {
history_.clear();
QListWidget::clear();
if (!silent) addEntry(-1);
emit clearAvailable(false);
emit redoAvailable(index < count());
emit undoAvailable((index > 1));
}
void HistoryView::undo() {
if (index <= 1) return;
index--;
emit commandExecute(history_[index - 1].command);
emit changed();
itemSelectionChanged();
}
void HistoryView::redo() {
if (index >= count()) return;
index++;
emit commandExecute(history_[index - 1].command);
emit changed();
itemSelectionChanged();
}

View File

@@ -0,0 +1,79 @@
#ifndef HISTORYVIEW_H
#define HISTORYVIEW_H
#include <QListWidget>
#include <QDebug>
class HistoryView: public QListWidget
{
Q_OBJECT
Q_PROPERTY(bool active READ isActive WRITE setActive)
Q_PROPERTY(bool duplicatesEnabled READ isDuplicatesEnabled WRITE setDuplicatesEnabled)
Q_PROPERTY(int limit READ limit WRITE setLimit)
Q_PROPERTY(QColor historyColor READ historyColor WRITE setHistoryColor)
public:
explicit HistoryView(QWidget * parent = 0);
~HistoryView();
bool isActive() const {return active_;}
bool isDuplicatesEnabled() const {return duplicates_;}
int limit() const {return limit_;}
QColor historyColor() const {return color_;}
QByteArray current() const;
void addEntry(int action, int count = 0, const QString & suffix = QString());
void registerAction(int action, const QString & text, const QImage & icon = QImage());
private:
struct Action {
Action(int i = -1, const QString & t = QString(), const QImage & c = QImage()): id(i), text(t) {
QPixmap px = QPixmap::fromImage(c);
icon.addPixmap(px, QIcon::Active);
icon.addPixmap(px, QIcon::Disabled);
icon.addPixmap(px, QIcon::Normal);
icon.addPixmap(px, QIcon::Selected);
}
int id;
QString text;
QIcon icon;
};
struct Entry {
Entry(int a = -1, const QByteArray & c = QByteArray()): action(a), command(c) {}
int action;
QByteArray command;
};
void checkLimit();
QString actionText(int action, int count_);
QMap<int, Action> actions_;
QVector<Entry> history_;
QColor color_;
bool active_, duplicates_;
int index, limit_;
public slots:
void setActive(bool yes) {active_ = yes;}
void setDuplicatesEnabled(bool yes) {duplicates_ = yes;}
void setLimit(int l);
void setHistoryColor(const QColor & c);
void clear(bool silent = false);
void undo();
void redo();
private slots:
void itemClicked(QListWidgetItem * item);
void itemSelectionChanged();
signals:
void undoAvailable(bool);
void redoAvailable(bool);
void clearAvailable(bool);
void commandRequest(QByteArray & s);
void commandExecute(const QByteArray & s);
void changed();
};
#endif // HISTORYVIEW_H

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="ru_RU">
<context>
<name>EMainWindow</name>
<message>
<location filename="../emainwindow.cpp" line="28"/>
<location filename="../emainwindow.cpp" line="29"/>
<source>Show all</source>
<translation>Показать все</translation>
</message>
<message>
<location filename="../emainwindow.cpp" line="30"/>
<location filename="../emainwindow.cpp" line="31"/>
<source>Hide all</source>
<translation>Скрыть все</translation>
</message>
<message>
<location filename="../emainwindow.cpp" line="125"/>
<source>Toolbars</source>
<translation>Панели инструментов</translation>
</message>
<message>
<location filename="../emainwindow.cpp" line="150"/>
<source>Docks</source>
<translation>Окна</translation>
</message>
<message>
<location filename="../emainwindow.cpp" line="309"/>
<source>Select file to open</source>
<translation>Выбрать файл для открытия</translation>
</message>
<message>
<location filename="../emainwindow.cpp" line="317"/>
<source>Save changes%1?</source>
<translation>Сохранить изменения%1?</translation>
</message>
<message>
<location filename="../emainwindow.cpp" line="317"/>
<source> in</source>
<translation> в</translation>
</message>
<message>
<location filename="../emainwindow.cpp" line="329"/>
<source>Select file to save</source>
<translation>Выберите файл для сохранения</translation>
</message>
</context>
<context>
<name>HistoryView</name>
<message>
<location filename="../historyview.cpp" line="15"/>
<source>History cleared</source>
<translation>История очищена</translation>
</message>
</context>
</TS>

View File

@@ -0,0 +1 @@
qad_plugin(application "Gui;Widgets" "")

View File

@@ -0,0 +1,69 @@
#include "edockwidget.h"
#include "edockwidgetplugin.h"
#include <QtCore/QtPlugin>
EDockWidgetPlugin::EDockWidgetPlugin(QObject * parent): QObject(parent) {
m_initialized = false;
}
void EDockWidgetPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized)
return;
// Add extension registrations, etc. here
m_initialized = true;
}
bool EDockWidgetPlugin::isInitialized() const {
return m_initialized;
}
QWidget * EDockWidgetPlugin::createWidget(QWidget * parent) {
return new EDockWidget(parent);
}
QString EDockWidgetPlugin::name() const {
return QLatin1String("EDockWidget");
}
QString EDockWidgetPlugin::group() const {
return QLatin1String("Containers");
}
QIcon EDockWidgetPlugin::icon() const {
return QIcon(":/icons/edockwidget.png");
}
QString EDockWidgetPlugin::toolTip() const {
return QLatin1String("");
}
QString EDockWidgetPlugin::whatsThis() const {
return QLatin1String("");
}
bool EDockWidgetPlugin::isContainer() const {
return true;
}
QString EDockWidgetPlugin::domXml() const {
return QLatin1String("<widget class=\"EDockWidget\" name=\"dockWidget\">\n</widget>\n");
}
QString EDockWidgetPlugin::includeFile() const {
return QLatin1String("edockwidget.h");
}

View File

@@ -0,0 +1,36 @@
#ifndef EDOCKWIDGETPLUGIN_H
#define EDOCKWIDGETPLUGIN_H
#include <QObject>
#if QT_VERSION >= 0x050000
# include <QtUiPlugin/QDesignerCustomWidgetInterface>
#else
# include <QDesignerCustomWidgetInterface>
#endif
class EDockWidgetPlugin: public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
EDockWidgetPlugin(QObject * parent = 0);
bool isContainer() const;
bool isInitialized() const;
QIcon icon() const;
QString domXml() const;
QString group() const;
QString includeFile() const;
QString name() const;
QString toolTip() const;
QString whatsThis() const;
QWidget * createWidget(QWidget * parent);
void initialize(QDesignerFormEditorInterface * core);
private:
bool m_initialized;
};
#endif

View File

@@ -0,0 +1,69 @@
#include "emainwindow.h"
#include "emainwindowplugin.h"
#include <QtCore/QtPlugin>
EMainWindowPlugin::EMainWindowPlugin(QObject * parent): QObject(parent) {
m_initialized = false;
}
void EMainWindowPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized)
return;
// Add extension registrations, etc. here
m_initialized = true;
}
bool EMainWindowPlugin::isInitialized() const {
return m_initialized;
}
QWidget * EMainWindowPlugin::createWidget(QWidget * parent) {
return new EMainWindow(parent);
}
QString EMainWindowPlugin::name() const {
return QLatin1String("EMainWindow");
}
QString EMainWindowPlugin::group() const {
return QLatin1String("Containers");
}
QIcon EMainWindowPlugin::icon() const {
return QIcon();
}
QString EMainWindowPlugin::toolTip() const {
return QLatin1String("");
}
QString EMainWindowPlugin::whatsThis() const {
return QLatin1String("");
}
bool EMainWindowPlugin::isContainer() const {
return true;
}
QString EMainWindowPlugin::domXml() const {
return QLatin1String("<widget class=\"EMainWindow\" name=\"mainWindow\">\n</widget>\n");
}
QString EMainWindowPlugin::includeFile() const {
return QLatin1String("emainwindow.h");
}

View File

@@ -0,0 +1,36 @@
#ifndef EMAINWINDOWPLUGIN_H
#define EMAINWINDOWPLUGIN_H
#include <QObject>
#if QT_VERSION >= 0x050000
# include <QtUiPlugin/QDesignerCustomWidgetInterface>
#else
# include <QDesignerCustomWidgetInterface>
#endif
class EMainWindowPlugin: public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
EMainWindowPlugin(QObject * parent = 0);
bool isContainer() const;
bool isInitialized() const;
QIcon icon() const;
QString domXml() const;
QString group() const;
QString includeFile() const;
QString name() const;
QString toolTip() const;
QString whatsThis() const;
QWidget * createWidget(QWidget * parent);
void initialize(QDesignerFormEditorInterface * core);
private:
bool m_initialized;
};
#endif

View File

@@ -0,0 +1,69 @@
#include "historyview.h"
#include "historyviewplugin.h"
#include <QtCore/QtPlugin>
HistoryViewPlugin::HistoryViewPlugin(QObject * parent): QObject(parent) {
m_initialized = false;
}
void HistoryViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
if (m_initialized)
return;
// Add extension registrations, etc. here
m_initialized = true;
}
bool HistoryViewPlugin::isInitialized() const {
return m_initialized;
}
QWidget * HistoryViewPlugin::createWidget(QWidget * parent) {
return new HistoryView(parent);
}
QString HistoryViewPlugin::name() const {
return QLatin1String("HistoryView");
}
QString HistoryViewPlugin::group() const {
return QLatin1String("Display Widgets");
}
QIcon HistoryViewPlugin::icon() const {
return QIcon(":/icons/historyview.png");
}
QString HistoryViewPlugin::toolTip() const {
return QLatin1String("");
}
QString HistoryViewPlugin::whatsThis() const {
return QLatin1String("");
}
bool HistoryViewPlugin::isContainer() const {
return true;
}
QString HistoryViewPlugin::domXml() const {
return QLatin1String("<widget class=\"HistoryView\" name=\"historyView\">\n</widget>\n");
}
QString HistoryViewPlugin::includeFile() const {
return QLatin1String("historyview.h");
}

View File

@@ -0,0 +1,36 @@
#ifndef HISTORYVIEWPLUGIN_H
#define HISTORYVIEWPLUGIN_H
#include <QObject>
#if QT_VERSION >= 0x050000
# include <QtUiPlugin/QDesignerCustomWidgetInterface>
#else
# include <QDesignerCustomWidgetInterface>
#endif
class HistoryViewPlugin: public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
HistoryViewPlugin(QObject * parent = 0);
bool isContainer() const;
bool isInitialized() const;
QIcon icon() const;
QString domXml() const;
QString group() const;
QString includeFile() const;
QString name() const;
QString toolTip() const;
QString whatsThis() const;
QWidget * createWidget(QWidget * parent);
void initialize(QDesignerFormEditorInterface * core);
private:
bool m_initialized;
};
#endif // HISTORYVIEWPLUGIN_H

View File

@@ -0,0 +1,21 @@
#include "qad_application.h"
#include "edockwidgetplugin.h"
#include "emainwindowplugin.h"
#include "historyviewplugin.h"
QADApplication::QADApplication(QObject * parent): QObject(parent) {
//m_widgets.append(new EDockWidgetPlugin(this));
m_widgets.append(new EMainWindowPlugin(this));
m_widgets.append(new HistoryViewPlugin(this));
}
QList<QDesignerCustomWidgetInterface * > QADApplication::customWidgets() const {
return m_widgets;
}
#if QT_VERSION < 0x050000
Q_EXPORT_PLUGIN2(qad_graphic_plugin, QADApplication)
#endif

View File

@@ -0,0 +1,23 @@
#ifndef QAD_APPLICATION_H
#define QAD_APPLICATION_H
#include <QtDesigner/QtDesigner>
#include <QtCore/qplugin.h>
class QADApplication: public QObject, public QDesignerCustomWidgetCollectionInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "qad.application")
#endif
public:
explicit QADApplication(QObject * parent = 0);
virtual QList<QDesignerCustomWidgetInterface * > customWidgets() const;
private:
QList<QDesignerCustomWidgetInterface * > m_widgets;
};
#endif // QAD_APPLICATION_H

View File

@@ -0,0 +1,31 @@
<RCC>
<qresource prefix="/">
<file>lang/qad_application_ru.ts</file>
<file>../icons/application-exit.png</file>
<file>../icons/dialog-close.png</file>
<file>../icons/configure.png</file>
<file>../icons/document-edit.png</file>
<file>../icons/document-new.png</file>
<file>../icons/document-save.png</file>
<file>../icons/document-save-all.png</file>
<file>../icons/document-save-as.png</file>
<file>../icons/document-open.png</file>
<file>../icons/document-open-recent.png</file>
<file>../icons/document-close.png</file>
<file>../icons/edit-clear.png</file>
<file>../icons/edit-clear-locationbar-rtl.png</file>
<file>../icons/edit-find.png</file>
<file>../icons/list-add.png</file>
<file>../icons/edit-delete.png</file>
<file>../icons/edit-copy.png</file>
<file>../icons/edit-paste.png</file>
<file>../icons/edit-undo.png</file>
<file>../icons/edit-redo.png</file>
<file>../icons/border-line.png</file>
<file>../icons/edockwidget.png</file>
<file>../icons/historyview.png</file>
<file>../icons/clear-history.png</file>
<file>../icons/layer-visible-off.png</file>
<file>../icons/layer-visible-on.png</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,87 @@
#include <QDebug>
#include "qsingleapplication.h"
#define QSA_SHMSIZE 4096
#define QSA_MSGSIZE (QSA_SHMSIZE - sizeof(quint32) - sizeof(quint32))
QSingleApplication::QSingleApplication(const QString & app_name): QThread() {
shm.setKey(app_name);
exiting = false;
first = !shm.attach();
if (!first) {
shm.detach();
first = !shm.attach();
if (!first)
return;
}
shm.create(QSA_SHMSIZE);
shm.attach();
shm.lock();
void * d = shm.data();
if (d) memset(d, 0, sizeof(quint32));
shm.unlock();
start();
//qDebug() << "start listen";
}
QSingleApplication::~QSingleApplication() {
if (first) {
exiting = true;
quit();
if (!wait(100))
terminate();
}
if (shm.isAttached()) shm.detach();
}
void QSingleApplication::sendMessage(const QByteArray & m) {
//qDebug() << "send message" << first << shm.isAttached();
if (first || !shm.isAttached()) return;
if (m.size() > int(QSA_MSGSIZE)) {
qDebug() << "[QSingleApplication] Too large message:" << m.size() << ">" << QSA_MSGSIZE;
return;
}
shm.lock();
quint32 num(0), size = m.size();
void * d = shm.data();
if (d) {
memcpy(&num, d, sizeof(quint32));
num++;
memcpy(d, &num, sizeof(quint32));
memcpy((((char*)d) + sizeof(quint32)), &size, sizeof(quint32));
memcpy((((char*)d) + sizeof(quint32) + sizeof(quint32)), m.constData(), size);
}
shm.unlock();
}
void QSingleApplication::run() {
quint32 num(0), pnum(0), size(0);
while (!exiting) {
shm.lock();
const void * d = shm.constData();
if (d) {
memcpy(&num, d, sizeof(quint32));
if (pnum != num) {
pnum = num;
//qDebug() << "new message" << num;
memcpy(&size, (((const char*)d) + sizeof(quint32)), sizeof(quint32));
if (size <= int(QSA_MSGSIZE)) {
QByteArray msg;
msg.resize(size);
memcpy(msg.data(), (((const char*)d) + sizeof(quint32) + sizeof(quint32)), size);
emit messageReceived(msg);
} else {
qDebug() << "[QSingleApplication] Invalid message size:" << size;
}
}
}
shm.unlock();
if (exiting) break;
msleep(10);
}
}

View File

@@ -0,0 +1,30 @@
#ifndef QSINGLEAPPLICATION_H
#define QSINGLEAPPLICATION_H
#include <QThread>
#include <QSharedMemory>
class QSingleApplication: public QThread
{
Q_OBJECT
public:
QSingleApplication(const QString & app_name = QString("qapp"));
~QSingleApplication();
bool isFirst() const {return first;}
private:
void run();
QSharedMemory shm;
bool first, exiting;
public slots:
void sendMessage(const QByteArray & m);
signals:
void messageReceived(QByteArray);
};
#endif // QSINGLEAPPLICATION_H

View File

@@ -0,0 +1,230 @@
#include "ribbon.h"
#include "qad_types.h"
#include <QScrollBar>
Ribbon::Ribbon(QMainWindow * parent_): QToolBar() {
tab = 0;
scroll_area = 0;
delay_e = true;
delay = 1000;
hovered = -1;
setObjectName("ribbon");
setProperty("ribbon", true);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
parent = parent_;
if (parent_)
parent_->installEventFilter(this);
init();
}
Ribbon::~Ribbon() {
}
bool Ribbon::eventFilter(QObject * o, QEvent * e) {
//qDebug() << e;
if (o == parent) {
if (e->type() == QEvent::Resize || e->type() == QEvent::WindowActivate)
_resize();
if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish)
_setIconsSize();
return QToolBar::eventFilter(o, e);
}
if (e->type() == QEvent::ActionChanged) {
QToolButton * b = qobject_cast<QToolButton * >((QObject * )o->property("ribbonButton").toLongLong());
if (b != 0)
b->setEnabled(qobject_cast<QAction * >(o)->isEnabled());
}
return QToolBar::eventFilter(o, e);
}
void Ribbon::timerEvent(QTimerEvent * e) {
if (hovers.value(e->timerId(), -1) == hovered)
tab->setCurrentIndex(hovered);
hovers.remove(e->timerId());
killTimer(e->timerId());
}
void Ribbon::_resize() {
return; // WARNING
for (int i = 0; i < tab->count(); ++i) {
int h = ((QScrollArea*)(tab->widget(i)))->sizeHint().height();
if (((QScrollArea*)(tab->widget(i)))->horizontalScrollBar()->isVisible())
h += ((QScrollArea*)(tab->widget(i)))->horizontalScrollBar()->height();
((QScrollArea*)(tab->widget(i)))->setMinimumHeight(h);
}
}
void Ribbon::_setIconsSize() {
//qDebug() << "resize" << preferredIconSize() << QApplication::font();
setTabIconSize(preferredIconSize(2, this));
setIconSize(preferredIconSize(3, this));
}
void Ribbon::setVisible(bool yes) {
QToolBar::setVisible(yes);
if (parent == 0) return;
if (parent->menuBar() == 0) return;
parent->menuBar()->setVisible(!yes);
}
void Ribbon::init() {
if (parent == 0) return;
if (parent->menuBar() == 0) return;
QList<QAction * > lm = parent->menuBar()->actions(), la;
clear();
if (scroll_area) delete scroll_area;
buttons.clear();
tab = new ETabWidget();
tab->setObjectName("ribbon_tab_widget");
connect(tab, SIGNAL(tabHovered(int)), this, SLOT(tabHovered(int)));
connect(tab, SIGNAL(currentChanged(int)), this, SIGNAL(currentTabChanged(int)));
tab->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
QFrame * g;
QBoxLayout * l, * tl;
QToolButton * b;
//tab->setIconSize(QSize(32, 32));
foreach (QAction * i, lm) {
if (!i->menu()) continue;
//if (!i->menu()->isVisible()) continue;
la = i->menu()->actions();
QIcon tic = i->icon();
if (!tic.isNull())
i->setProperty("__icon", QVariant::fromValue<QIcon>(tic));
else
tic = i->property("__icon").value<QIcon>();
//#ifdef Q_OS_MACOS
// tic = QIcon();
//#endif
tab->addTab(new QWidget(), tic, i->text());
//qDebug() << this << i->icon() << i->text();
//continue;
/*QScrollArea * sa = new QScrollArea();
sa->setWidget(new QWidget());
sa->setWidgetResizable(true);
sa->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
sa->setFrameShape(QFrame::NoFrame);
tab->addTab(sa, i->icon(), i->text());*/
tab->widget(tab->count() - 1)->setProperty("ribbonAction", qlonglong((void * )i));
i->setIcon(QIcon());
tl = new QBoxLayout(QBoxLayout::LeftToRight);
tl->setSpacing(2);
#ifndef Q_OS_MACOS
tl->setContentsMargins(2, 2, 2, 2);
#else
tl->setContentsMargins(2, 0, 2, 2);
#endif
g = new QFrame(); g->setFrameShape(QFrame::StyledPanel);
l = new QBoxLayout(QBoxLayout::LeftToRight);
g->setLayout(l);
l->setSpacing(2);
l->setContentsMargins(2, 2, 2, 2);
foreach (QAction * j, la) {
if (j->isSeparator()) {
if (l->isEmpty()) continue;
tl->addWidget(g);
g = new QFrame(); g->setFrameShape(QFrame::StyledPanel);
l = new QBoxLayout(QBoxLayout::LeftToRight);
l->setSpacing(2);
l->setContentsMargins(2, 2, 2, 2);
g->setLayout(l);
continue;
}
if (qobject_cast<QWidgetAction*>(j)) {
QWidget * _w = qobject_cast<QWidgetAction*>(j)->defaultWidget();
l->addWidget(_w);
_w->show();
continue;
}
b = new QToolButton();
b->setEnabled(j->isEnabled());
b->setProperty("ribbonAction", qlonglong((void * )j));
j->setProperty("ribbonButton", qlonglong((void * )b));
j->installEventFilter(this);
if (j->menu() != 0) {
b->setPopupMode(QToolButton::InstantPopup);
b->setMenu(j->menu());
} else {
b->setCheckable(j->isCheckable());
if (b->isCheckable()) {
b->setChecked(j->isChecked());
connect(b, SIGNAL(toggled(bool)), j, SLOT(setChecked(bool)));
connect(b, SIGNAL(clicked(bool)), j, SIGNAL(triggered(bool)));
connect(j, SIGNAL(toggled(bool)), b, SLOT(setChecked(bool)));
} else
connect(b, SIGNAL(clicked()), j, SLOT(trigger()));
}
//b->setIconSize(QSize(16, 16));
b->setIcon(j->icon());
b->setText(j->text());
b->setToolTip(j->text());
//b->addAction(j);
//b->setShortcut(j->shortcut());
b->setAutoRaise(true);
b->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
b->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
buttons << b;
l->addWidget(b);
}
tl->addWidget(g);
tl->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed));
//sa->widget()->setLayout(tl);
tab->widget(tab->count() - 1)->setLayout(tl);
}
setFloatable(false);
setMovable(false);
/*scroll_area = new QScrollArea();
scroll_area->setFrameShape(QFrame::NoFrame);
scroll_area->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scroll_area->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
scroll_area->setWidget(tab);*/
_resize();
//addWidget(scroll_area);
addWidget(tab);
parent->addToolBar(Qt::TopToolBarArea, this);
parent->menuBar()->hide();
tab->setAutoFillBackground(false);
_setIconsSize();
}
void Ribbon::retranslate() {
QAction * a;
foreach (QToolButton * i, buttons) {
a = (QAction * )(i->property("ribbonAction").toLongLong());
if (a == 0) continue;
i->setText(a->text());
i->setToolTip(a->toolTip());
//i->setShortcut(a->shortcut());
}
for (int i = 0; i < tab->count(); ++i) {
a = (QAction * )(tab->widget(i)->property("ribbonAction").toLongLong());
if (a == 0) continue;
tab->setTabText(i, a->text());
}
_resize();
}
void Ribbon::setIconSize(const QSize & size) {
foreach (QToolButton * i, buttons)
i->setIconSize(size);
_resize();
}
void Ribbon::setTabIconSize(const QSize & size) {
#ifndef Q_OS_MACOS
tab->setIconSize(size);
#endif
_resize();
}

View File

@@ -0,0 +1,63 @@
#ifndef RIBBON_H
#define RIBBON_H
#include <QMainWindow>
#include <QActionGroup>
#include <QWidgetAction>
#include <QMenuBar>
#include <QTabWidget>
#include <QGroupBox>
#include <QDockWidget>
#include <QToolBar>
#include <QToolButton>
#include <QScrollArea>
#include "etabwidget.h"
class Ribbon: public QToolBar
{
Q_OBJECT
public:
explicit Ribbon(QMainWindow * parent = 0);
~Ribbon();
void init();
void retranslate();
void setIconSize(const QSize & size);
void setTabIconSize(const QSize & size);
void setButtonStyle(const Qt::ToolButtonStyle & style) {foreach (QToolButton * i, buttons) i->setToolButtonStyle(style);}
void setAutoSwitchEnabled(bool yes) {delay_e = yes;}
void setAutoSwitchDelay(float delay_s) {delay = delay_s * 1000;}
void setCurrentTab(int tab_) {if (tab_ < 0 || tab_ >= tab->count()) return; tab->setCurrentIndex(tab_);}
int currentTab() const {return tab->currentIndex();}
QTabWidget * tabWidget() const {return tab;}
private:
bool eventFilter(QObject * o, QEvent * e);
void timerEvent(QTimerEvent * e);
void _resize();
void _setIconsSize();
int hovered, delay;
bool delay_e;
QList<QToolButton * > buttons;
QMap<int, int> hovers;
ETabWidget * tab;
QScrollArea * scroll_area;
QMainWindow * parent;
private slots:
void tabHovered(int tab) {if (!delay_e) return; hovers.clear(); hovered = tab; hovers.insert(startTimer(delay), tab);}
public slots:
void setVisible(bool yes);
void setHidden(bool yes) {setVisible(!yes);}
void show() {setVisible(true);}
void hide() {setVisible(false);}
signals:
void currentTabChanged(int);
};
#endif // RIBBON_H