diff --git a/patches/dev/psiplus-decorate-windows_fixed.diff b/patches/dev/psiplus-decorate-windows_fixed.diff new file mode 100644 index 0000000..51a969f --- /dev/null +++ b/patches/dev/psiplus-decorate-windows_fixed.diff @@ -0,0 +1,1121 @@ +--- git.orig/options/default.xml ++++ git/options/default.xml +@@ -446,6 +446,7 @@ QLineEdit#le_status_text { + + true + ++ true + + false + false +--- git.orig/src/groupchatdlg.cpp ++++ git/src/groupchatdlg.cpp +@@ -85,6 +85,7 @@ + #include "mcmdmanager.h" + #include "lastactivitytask.h" + #include "psirichtext.h" ++#include "psiwindowheader.h" + + #include "mcmdsimplesite.h" + +@@ -237,9 +238,13 @@ public: + + int logSize; + int rosterSize; ++ + public: + bool trackBar; + ++ bool tabmode; ++ PsiWindowHeader *winHeader_; ++ + public: + ChatEdit* mle() const { return dlg->ui_.mle->chatEdit(); } + ChatView* te_log() const { return dlg->ui_.log; } +@@ -631,6 +636,14 @@ GCMainDlg::GCMainDlg(PsiAccount *pa, con + ui_.lb_ident->setAccount(account()); + ui_.lb_ident->setShowJid(false); + ui_.log->setSessionData(true, jid().full(), jid().full()); //FIXME change conference name ++ d->tabmode = PsiOptions::instance()->getOption("options.ui.tabs.use-tabs").toBool(); ++ setWindowBorder(PsiOptions::instance()->getOption("options.ui.decorate-windows").toBool()); ++ if (!d->tabmode && !isBorder()) { ++ d->winHeader_ = new PsiWindowHeader(this); ++ ui_.vboxLayout1->insertWidget(0, d->winHeader_); ++ } ++ setMargins(); ++ + #ifdef WEBKIT + ui_.log->setAccount(account()); + #endif +@@ -2097,6 +2110,25 @@ void GCMainDlg::resizeEvent(QResizeEvent + QTimer::singleShot(0, this, SLOT(horizSplitterMoved())); + } + ++void GCMainDlg::setMargins() ++{ ++ ui_.vboxLayout->setContentsMargins(0,0,0,0); ++ ui_.vboxLayout2->setContentsMargins(4,0,4,4); ++ if (!d->tabmode) { ++ ui_.hboxLayout->setContentsMargins(4,0,4,0); ++ if (!isBorder()) { ++ ui_.vboxLayout1->setContentsMargins(0,0,0,0); ++ } ++ else { ++ ui_.vboxLayout1->setContentsMargins(0,4,0,0); ++ } ++ } ++ else { ++ ui_.vboxLayout1->setContentsMargins(4,4,4,0); ++ ui_.hboxLayout->setContentsMargins(2,0,4,0); ++ } ++} ++ + //---------------------------------------------------------------------------- + // GCFindDlg + //---------------------------------------------------------------------------- +--- git.orig/src/groupchatdlg.h ++++ git/src/groupchatdlg.h +@@ -169,6 +169,8 @@ private: + + PsiOptions* options_; + QDateTime lastMsgTime_; ++ ++ void setMargins(); + }; + + class GCFindDlg : public QDialog +--- git.orig/src/mainwin.cpp ++++ git/src/mainwin.cpp +@@ -147,6 +147,8 @@ public: + QTimer *hideTimer; + int hideTimerInterval; //interval in sec + bool useAutohide; ++ bool isHide; ++ + + #ifdef Q_WS_WIN + DWORD deactivationTickCount; +@@ -572,6 +574,8 @@ MainWin::MainWin(bool _onTop, bool _asTo + d->hideTimerInterval = PsiOptions::instance()->getOption("options.contactlist.autohide-interval").toInt(); + d->hideTimer->setInterval(d->hideTimerInterval*1000); + optionChanged("options.contactlist.use-autohide"); ++ setWindowBorder(PsiOptions::instance()->getOption("options.ui.decorate-windows").toBool()); ++ setMouseTracking(!isBorder()); + } + + MainWin::~MainWin() +@@ -628,6 +632,11 @@ void MainWin::optionChanged(const QStrin + if(d->useAutohide) + d->hideTimer->start(); + } ++ else if (option == "options.ui.decorate-windows") { ++ setWindowBorder(PsiOptions::instance()->getOption("options.ui.decorate-windows").toBool()); ++ setMouseTracking(!isBorder()); ++ show(); ++ } + } + + void MainWin::hideTimerTimeout() +@@ -797,14 +806,19 @@ void MainWin::setWindowOpts(bool _onTop, + d->onTop = _onTop; + d->asTool = _asTool; + +- Qt::WFlags flags = 0; ++ Qt::WFlags flags = windowFlags(); + if(d->onTop) { + flags |= Qt::WindowStaysOnTopHint; + } ++ else { ++ flags &= ~Qt::WindowStaysOnTopHint; ++ } + if(d->asTool) { + flags |= Qt::Tool | TOOLW_FLAGS; + } +- ++ else { ++ flags &= ~Qt::Tool; ++ } + setWindowFlags(flags); + show(); + } +@@ -1733,6 +1747,7 @@ void MainWin::statusClicked(int x) + { + if(x == Qt::MidButton) { + recvNextEvent(); ++ d->isHide = false; + } + } + +@@ -1986,4 +2001,32 @@ void MainWin::resizeEvent(QResizeEvent * + } + } + ++void MainWin::mousePressEvent(QMouseEvent *e) ++{ ++ if (e->button() == Qt::MidButton && !isBorder()) { ++ d->isHide = true; ++ } ++ ++ AdvancedWidget::mousePressEvent(e); ++} ++ ++void MainWin::mouseReleaseEvent(QMouseEvent *e) ++{ ++ if (e->button() == Qt::MidButton && !isBorder() && d->isHide) { ++ d->isHide = false; ++ if (e->globalPos().x() >= geometry().left() ++ && e->globalPos().x() <= geometry().right() ++ && e->globalPos().y() >= geometry().top() ++ && e->globalPos().y() <= geometry().bottom()){ ++ if (d->asTool){ ++ d->mainWin->trayHide(); ++ } else { ++ setWindowState(windowState() | Qt::WindowMinimized); ++ } ++ } ++ } ++ ++ AdvancedWidget::mouseReleaseEvent(e); ++} ++ + //#endif +--- git.orig/src/mainwin.h ++++ git/src/mainwin.h +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #include "advwidget.h" + #include "xmpp_status.h" +@@ -84,6 +85,8 @@ protected: + #ifdef Q_WS_WIN + bool winEvent(MSG *, long *); + #endif ++ void mousePressEvent(QMouseEvent *e); ++ void mouseReleaseEvent(QMouseEvent *e); + + signals: + void statusChanged(XMPP::Status::Type); +--- git.orig/src/options/opt_application.cpp ++++ git/src/options/opt_application.cpp +@@ -43,7 +43,9 @@ QWidget *OptionsTabApplication::widget() + + w = new OptApplicationUI(); + OptApplicationUI *d = (OptApplicationUI *)w; +- ++ d->ck_winDecor->setWhatsThis( ++ tr("Set or remove window decorations for roster and chats." ++ " For chats there are special header with close, hide and maximize buttons")); + // docklet + d->ck_docklet->setWhatsThis( + tr("Makes Psi use a docklet icon, also known as system tray icon.")); +@@ -90,6 +92,7 @@ void OptionsTabApplication::applyOptions + OptApplicationUI *d = (OptApplicationUI *)w; + + PsiOptions::instance()->setOption("options.ui.contactlist.quit-on-close", d->ck_quitOnClose->isChecked()); ++ PsiOptions::instance()->setOption("options.ui.decorate-windows", d->ck_winDecor->isChecked()); + + // Auto-update + PsiOptions::instance()->setOption("options.auto-update.check-on-startup", d->ck_autoUpdate->isChecked()); +@@ -134,6 +137,7 @@ void OptionsTabApplication::restoreOptio + + d->ck_autoUpdate->setChecked(PsiOptions::instance()->getOption("options.auto-update.check-on-startup").toBool()); + d->ck_quitOnClose->setChecked(PsiOptions::instance()->getOption("options.ui.contactlist.quit-on-close").toBool()); ++ d->ck_winDecor->setChecked(PsiOptions::instance()->getOption("options.ui.decorate-windows").toBool()); + + // docklet + d->ck_docklet->setChecked( PsiOptions::instance()->getOption("options.ui.systemtray.enable").toBool() ); +--- git.orig/src/options/opt_application.ui ++++ git/src/options/opt_application.ui +@@ -24,6 +24,16 @@ + + + ++ ++ ++ Decorate windows ++ ++ ++ true ++ ++ ++ ++ + + + Docklet +@@ -227,6 +237,7 @@ + ck_useleft + ck_showMenubar + ck_docklet ++ ck_winDecor + ck_dockDCstyle + ck_dockHideMW + ck_dockToolMW +--- git.orig/src/psichatdlg.cpp ++++ git/src/psichatdlg.cpp +@@ -175,6 +175,8 @@ PsiChatDlg::PsiChatDlg(const Jid& jid, P + connect(account(), SIGNAL(removedContact(PsiContact*)), SLOT(updateContactAdding(PsiContact*))); + connect(account(), SIGNAL(updateContact(const Jid &)), SLOT(updateContactAdding(const Jid &))); + mCmdManager_.registerProvider(new ChatDlgMCmdProvider(this)); ++ tabmode = PsiOptions::instance()->getOption("options.ui.tabs.use-tabs").toBool(); ++ setWindowBorder(PsiOptions::instance()->getOption("options.ui.decorate-windows").toBool()); + + SendButtonTemplatesMenu* menu = getTemplateMenu(); + if (menu) { +@@ -255,6 +257,12 @@ void PsiChatDlg::initUi() + + connect(act_minimize_, SIGNAL(triggered()), SLOT(doMinimize())); + addAction(act_minimize_); ++ ++ if (!tabmode) { ++ winHeader_ = new PsiWindowHeader(this); ++ ui_.vboxLayout1->insertWidget(0, winHeader_); ++ } ++ setMargins(); + } + + void PsiChatDlg::updateCountVisibility() +@@ -483,6 +491,22 @@ void PsiChatDlg::activated() + ChatDlg::activated(); + + updateCountVisibility(); ++ ++ bool border = PsiOptions::instance()->getOption("options.ui.decorate-windows").toBool(); ++ if (!PsiOptions::instance()->getOption("options.ui.tabs.use-tabs").toBool()){ ++ if (!winHeader_.isNull()) ++ winHeader_->setVisible(!border); ++ setWindowBorder(border); ++ setMargins(); ++#if defined(Q_WS_MAC) || defined(Q_WS_HAIKU) ++ // ++#else ++ bringToFront(true); ++#endif ++ } else { ++ if (!winHeader_.isNull()) ++ winHeader_->setVisible(false); ++ } + } + + void PsiChatDlg::setContactToolTip(QString text) +@@ -788,4 +812,23 @@ void PsiChatDlg::sendTemp(const QString + } + } + ++void PsiChatDlg::setMargins() ++{ ++ ui_.vboxLayout->setContentsMargins(0,0,0,0); ++ ui_.vboxLayout2->setContentsMargins(4,0,4,4); ++ if (!tabmode) { ++ ui_.hboxLayout->setContentsMargins(4,0,4,0); ++ if (!isBorder()) { ++ ui_.vboxLayout1->setContentsMargins(0,0,0,0); ++ } ++ else { ++ ui_.vboxLayout1->setContentsMargins(0,4,0,0); ++ } ++ } ++ else { ++ ui_.vboxLayout1->setContentsMargins(4,4,4,0); ++ ui_.hboxLayout->setContentsMargins(2,0,4,0); ++ } ++} ++ + #include "psichatdlg.moc" +--- git.orig/src/psichatdlg.h ++++ git/src/psichatdlg.h +@@ -9,6 +9,7 @@ + + #include "ui_chatdlg.h" + #include "typeaheadfind.h" ++#include "psiwindowheader.h" + + class IconAction; + class PsiContact; +@@ -70,6 +71,7 @@ private: + void appendSysMsg(const QString &); + ChatView* chatView() const; + ChatEdit* chatEdit() const; ++ void setMargins(); + + private: + Ui::ChatDlg ui_; +@@ -99,6 +101,11 @@ private: + + bool smallChat_; + class ChatDlgMCmdProvider; ++ ++private: ++ bool tabmode; ++ QPointer winHeader_; ++ + }; + + #endif +--- git.orig/src/tabs/tabdlg.cpp ++++ git/src/tabs/tabdlg.cpp +@@ -165,9 +165,19 @@ TabDlg::TabDlg(TabManager* tabManager, c + delegate_->tabWidgetCreated(this, tabWidget_); + + QVBoxLayout *vert1 = new QVBoxLayout(this); +- vert1->setMargin(1); ++ //Add windowheader widget if window not decorated ++ if (!PsiOptions::instance()->getOption("options.ui.decorate-windows").toBool() ++ && !PsiOptions::instance()->getOption("options.ui.tabs.grouping").toString().contains('A')) { ++ winHeader_ = new PsiWindowHeader(this); ++ vert1->addWidget(winHeader_); ++ vert1->setSpacing(0); ++ vert1->setMargin(0); ++ } else { ++ vert1->setMargin(1); ++ } + vert1->addWidget(tabWidget_); + ++ + setAcceptDrops(true); + + X11WM_CLASS("tabs"); +@@ -198,6 +208,7 @@ TabDlg::TabDlg(TabManager* tabManager, c + + if(!PsiOptions::instance()->getOption("options.ui.tabs.grouping").toString().contains('A')) + setGeometryOptionPath(geometryOption); ++ setWindowBorder(PsiOptions::instance()->getOption("options.ui.decorate-windows").toBool()); + } + + TabDlg::~TabDlg() +--- git.orig/src/tabs/tabdlg.h ++++ git/src/tabs/tabdlg.h +@@ -29,6 +29,7 @@ + #include "advwidget.h" + + #include "tabbablewidget.h" ++#include "psiwindowheader.h" + + class PsiCon; + class ChatTabs; +@@ -166,6 +167,7 @@ private: + void extinguishFlashingTabs(); + void updateCaption(); + void updateTabBar(); ++ PsiWindowHeader *winHeader_; + }; + + #endif +--- git.orig/src/tools/advwidget/advwidget.h ++++ git/src/tools/advwidget/advwidget.h +@@ -21,6 +21,7 @@ + #ifndef ADVWIDGET_H + #define ADVWIDGET_H + ++#include + #include + + class GAdvancedWidget : public QObject +@@ -65,6 +66,81 @@ class AdvancedWidget : public BaseClass + { + private: + GAdvancedWidget *gAdvWidget; ++#ifdef Q_OS_WIN ++ Qt::WindowFlags deltaflags; ++#endif ++ QPoint movepath; ++ bool isResize; ++ bool isDrag; ++ bool border; ++ QMap regions; ++ void mouseEnterEvent(const int mouse_x, const int mouse_y, const QRect &geom) ++ { ++ const int top = geom.top(); ++ const int bottom = geom.bottom(); ++ const int left = geom.left(); ++ const int right = geom.right(); ++ const int delta = 10; ++ const int maxtop = top + delta; ++ const int minbottom = bottom -delta; ++ if(mouse_y <= bottom ++ && mouse_y >= minbottom ++ && qAbs(mouse_x - left) < delta) { ++ setMouseRegion("leftbottom"); ++ } ++ else if (mouse_x > (left + delta) ++ && mouse_x < (right - delta) ++ && qAbs(mouse_y - bottom) < delta) { ++ setMouseRegion("bottom"); ++ } ++ else if ((bottom - mouse_y) < delta ++ && qAbs(mouse_x - right) < delta){ ++ setMouseRegion("rightbottom"); ++ } ++ else if ((right - mouse_x) < delta ++ && mouse_y > maxtop ++ && mouse_y < minbottom) { ++ setMouseRegion("right"); ++ } ++ else if ((mouse_x - left) < delta ++ && mouse_y > maxtop ++ && mouse_y < minbottom) { ++ setMouseRegion("left"); ++ } ++ else if ((top - mouse_y) < delta ++ && mouse_x > (left + delta) ++ && mouse_x < (right -delta)){ ++ setMouseRegion("top"); ++ } ++ else if ((top - mouse_y) < delta ++ && qAbs(mouse_x - right) < delta){ ++ setMouseRegion("righttop"); ++ } ++ else if ((top - mouse_y) < delta ++ && qAbs(mouse_x - left) < delta){ ++ setMouseRegion("lefttop"); ++ } ++ else { ++ setMouseRegion(""); ++ } ++ } ++ void setMouseRegion(const QString ®ion) ++ { ++ foreach(const QString &item, regions.keys()) { ++ regions.insert(item, false); ++ } ++ if (!region.isEmpty()) { ++ regions.insert(region, true); ++ } ++ } ++ bool getMouseRegion() ++ { ++ foreach(bool value, regions) { ++ if (value) ++ return value; ++ } ++ return false; ++ } + + public: + AdvancedWidget(QWidget *parent = 0, Qt::WindowFlags f = 0) +@@ -73,6 +149,7 @@ public: + { + if (f != 0) + BaseClass::setWindowFlags(f); ++ border = true; + gAdvWidget = new GAdvancedWidget( this ); + } + +@@ -151,6 +228,46 @@ public: + windowTitleChanged(); + } + ++ void setWindowBorder(bool isDecorated) ++ { ++ Qt::WindowFlags flags = BaseClass::windowFlags(); ++#ifdef Q_OS_WIN ++ if (deltaflags == 0) { ++ deltaflags = flags; ++ } ++ if (isDecorated) { ++ if (flags != deltaflags) { ++ flags |= Qt::WindowTitleHint; ++ flags &= ~Qt::FramelessWindowHint; ++ deltaflags = 0; ++ if (flags != BaseClass::windowFlags()) { ++ setWindowFlags(flags); ++ } ++ } ++ } else { ++ flags &= ~Qt::WindowTitleHint; ++ flags |= Qt::FramelessWindowHint; ++ if (flags != BaseClass::windowFlags()) { ++ setWindowFlags(flags); ++ } ++ ++ } ++#else ++ if (isDecorated) { ++ flags &= ~Qt::FramelessWindowHint; ++ } else { ++ flags |= Qt::FramelessWindowHint; ++ } ++ if (flags != BaseClass::windowFlags()) { ++ setWindowFlags(flags); ++ } ++#endif ++ border = isDecorated; ++ } ++ bool isBorder(){ ++ return border; ++ } ++ + protected: + virtual void windowTitleChanged() + { +@@ -165,6 +282,122 @@ protected: + } + BaseClass::changeEvent(event); + } ++ ++protected: ++ void setWindowFlags(Qt::WindowFlags flags){ ++ BaseClass::setWindowFlags(flags); ++ } ++ void mousePressEvent(QMouseEvent *event) ++ { ++ QWidget *window = BaseClass::window(); ++ if (!border && (event->button()==Qt::LeftButton)) { ++ mouseEnterEvent(event->globalPos().x(), event->globalPos().y(), window->geometry()); ++ if (getMouseRegion()) { ++ isResize = true; ++ } ++ else{ ++ movepath = event->globalPos() - window->pos(); ++ isResize = false; ++ } ++ isDrag = true; ++ BaseClass::mousePressEvent(event); ++ } ++ } ++ void mouseMoveEvent(QMouseEvent *event) ++ { ++ bool isLeftButton = (event->buttons() & Qt::LeftButton); ++ const QPoint pg = event->globalPos(); ++ QWidget *window = BaseClass::window(); ++ int ypath = 0; ++ int xpath = 0; ++ const int right = window->geometry().right(); ++ const int left = window->geometry().left(); ++ const int top = window->geometry().top(); ++ const int bottom = window->geometry().bottom(); ++ if (isLeftButton && regions.value("leftbottom") && isResize && !border) { ++ window->setCursor(QCursor(Qt::SizeBDiagCursor)); ++ ypath = pg.y() - bottom; ++ xpath = left - pg.x(); ++ if ((window->width() + xpath) < window->minimumWidth()) { ++ xpath = window->minimumWidth() - window->width(); ++ } ++ window->setGeometry(window->x() - xpath, window->y(), window->width() + xpath, window->height() + ypath); ++ ++ } ++ else if (isLeftButton && regions.value("rightbottom") && isResize && !border) { ++ window->setCursor(QCursor(Qt::SizeFDiagCursor)); ++ ypath = pg.y() - bottom; ++ xpath = pg.x() - right; ++ window->resize(window->width() + xpath, window->height() + ypath); ++ ++ } ++ else if (isLeftButton && regions.value("lefttop") && isResize && !border) { ++ window->setCursor(QCursor(Qt::SizeFDiagCursor)); ++ ypath = top - pg.y(); ++ xpath = left - pg.x(); ++ if ((window->width() + xpath) < window->minimumWidth()) { ++ xpath = window->minimumWidth() - window->width(); ++ } ++ if ((window->height() + ypath) < window->minimumHeight()) { ++ ypath = window->minimumHeight() - window->height(); ++ } ++ window->setGeometry(window->x() - xpath, window->y() - ypath, window->width() + xpath, window->height() + ypath); ++ } ++ else if (isLeftButton && regions.value("righttop") && isResize && !border) { ++ window->setCursor(QCursor(Qt::SizeBDiagCursor)); ++ ypath = top - pg.y(); ++ xpath = pg.x() - right; ++ if ((window->width() + xpath) < window->minimumWidth()) { ++ xpath = window->minimumWidth() - window->width(); ++ } ++ if ((window->height() + ypath) < window->minimumHeight()) { ++ ypath = window->minimumHeight() - window->height(); ++ } ++ window->setGeometry(window->x(), window->y() - ypath, window->width() + xpath, window->height() + ypath); ++ } ++ else if (isLeftButton && regions.value("bottom") && isResize && !border) { ++ window->setCursor(QCursor(Qt::SizeVerCursor)); ++ ypath = pg.y() - bottom; ++ window->resize(window->width(), window->height() + ypath); ++ } ++ else if (isLeftButton && regions.value("right") && isResize && !border) { ++ window->setCursor(QCursor(Qt::SizeHorCursor)); ++ xpath = pg.x() - right; ++ window->resize(window->width() + xpath, window->height()); ++ } ++ else if (isLeftButton && regions.value("left") && isResize && !border) { ++ window->setCursor(QCursor(Qt::SizeHorCursor)); ++ xpath = left - pg.x(); ++ if ((window->width() + xpath) < window->minimumWidth()) { ++ xpath = window->minimumWidth() - window->width(); ++ } ++ window->setGeometry(window->x() - xpath, window->y(), window->width() + xpath, window->height()); ++ } ++ else if (isLeftButton && regions.value("top") && isResize && !border) { ++ window->setCursor(QCursor(Qt::SizeVerCursor)); ++ ypath = top - pg.y(); ++ if ((window->height() + ypath) < window->minimumHeight()) { ++ ypath = window->minimumHeight() - window->height(); ++ } ++ window->setGeometry(window->x(), window->y() - ypath, window->width(), window->height() + ypath); ++ } ++ else if(isLeftButton && isDrag && !isResize && !border) { ++ window->setCursor(QCursor(Qt::ArrowCursor)); ++ window->move( event->globalPos() - movepath ); ++ } ++ BaseClass::mouseMoveEvent(event); ++ } ++ void mouseReleaseEvent(QMouseEvent *event) ++ { ++ QWidget *window = BaseClass::window(); ++ if (!border && (event->button() == Qt::LeftButton) && isDrag) { ++ movepath = QPoint(0,0); ++ isDrag = false; ++ isResize = false; ++ window->setCursor(QCursor(Qt::ArrowCursor)); ++ BaseClass::mouseReleaseEvent(event); ++ } ++ } + }; + + #endif +--- git.orig/src/widgets/psiwindowheader.cpp ++++ git/src/widgets/psiwindowheader.cpp +@@ -0,0 +1,228 @@ ++/* ++ * psiwindowheader.cpp ++ * Copyright (C) 2010 Khryukin Evgeny, Vitaly Tonkacheyev ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++ ++#include ++#include ++ ++#include "psiwindowheader.h" ++#include "psiiconset.h" ++ ++PsiWindowHeader::PsiWindowHeader(QWidget *p) ++ : QWidget(p), ++ maximized(false), ++ defaultSize(QSize(320, 280)) ++{ ++ parent_ = p->window(); ++ ui_.setupUi(this); ++ ui_.hideButton->setIcon(qApp->style()->standardIcon(QStyle::SP_TitleBarMinButton)); ++ ui_.maximizeButton->setIcon(qApp->style()->standardIcon(QStyle::SP_TitleBarMaxButton)); ++ ui_.closeButton->setIcon(qApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton)); ++ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); ++ ++ connect(ui_.hideButton, SIGNAL(clicked()), SLOT(hidePressed())); ++ connect(ui_.closeButton, SIGNAL(clicked()), SLOT(closePressed())); ++ connect(ui_.maximizeButton, SIGNAL(clicked()), SLOT(maximizePressed())); ++ setMouseTracking(true); ++} ++ ++PsiWindowHeader::~PsiWindowHeader() ++{ ++} ++ ++void PsiWindowHeader::hidePressed() ++{ ++ parent_->setWindowState(parent_->windowState() | Qt::WindowMinimized); ++} ++ ++void PsiWindowHeader::closePressed() ++{ ++ parent_->close(); ++} ++ ++void PsiWindowHeader::maximizePressed() ++{ ++ if (!maximized) { ++ if (parent_->window()->width() != qApp->desktop()->width() ++ && parent_->window()->height() != qApp->desktop()->height()) { ++ oldSize = parent_->window()->geometry(); ++ parent_->window()->setGeometry(qApp->desktop()->availableGeometry(-1)); ++ maximized = true; ++ } else { ++ parent_->window()->resize(defaultSize); ++ maximized = false; ++ } ++ } else { ++ parent_->window()->setGeometry(oldSize); ++ maximized = false; ++ } ++} ++ ++void PsiWindowHeader::mouseDoubleClickEvent(QMouseEvent *e) ++{ ++ if (e->button() == Qt::LeftButton) { ++ maximizePressed(); ++ e->accept(); ++ } ++} ++ ++void PsiWindowHeader::mousePressEvent(QMouseEvent *e) ++{ ++ if (e->button() == Qt::LeftButton) { ++ mouseEnterEvent(e->pos().x(),e->pos().y(),geometry()); ++ if (inVRect || inLDRect || inRDRect) { ++ isResize = true; ++ } ++ else{ ++ movepath = e->pos(); ++ isResize = false; ++ } ++ isDrag = true; ++ e->accept(); ++ } ++} ++ ++void PsiWindowHeader::mouseMoveEvent(QMouseEvent *e) ++{ ++ bool isLeftButton = (e->buttons() & Qt::LeftButton); ++ const QPoint pg = e->globalPos(); ++ int ypath = 0; ++ int xpath = 0; ++ if (isLeftButton && inLDRect && isResize) { ++ setCursor(QCursor(Qt::SizeFDiagCursor)); ++ if (pg.y() < parent_->window()->y()) { ++ ypath = parent_->window()->y() - pg.y(); ++ } ++ else { ++ ypath = -(pg.y() - parent_->window()->y()); ++ } ++ if (pg.x() < parent_->window()->x()) { ++ xpath = parent_->window()->x() - pg.x(); ++ } ++ else { ++ xpath = -(pg.x() - parent_->window()->x()); ++ } ++ if ((parent_->window()->width() + xpath) < parent_->window()->minimumWidth()) { ++ xpath = -(parent_->window()->width() - parent_->window()->minimumWidth()); ++ } ++ if ((parent_->window()->height() + ypath) < parent_->window()->minimumHeight()) { ++ ypath = -(parent_->window()->height() - parent_->window()->minimumHeight()); ++ } ++ parent_->window()->setGeometry(parent_->window()->x() - xpath, ++ parent_->window()->y() - ypath, ++ parent_->window()->width() + xpath, ++ parent_->window()->height() + ypath); ++ ++ } ++ else if (isLeftButton && inVRect && isResize) { ++ setCursor(QCursor(Qt::SizeVerCursor)); ++ if (pg.y() < parent_->window()->y()) { ++ ypath = parent_->window()->y() - pg.y(); ++ } ++ else { ++ ypath = -(pg.y() - parent_->window()->y()); ++ } ++ if ((parent_->window()->height() + ypath) < parent_->window()->minimumHeight()) { ++ ypath = -(parent_->window()->height() - parent_->window()->minimumHeight()); ++ } ++ parent_->window()->setGeometry(parent_->window()->x(), ++ parent_->window()->y() - ypath, ++ parent_->window()->width(), ++ parent_->window()->height() + ypath); ++ } ++ else if (isLeftButton && inRDRect && isResize) { ++ setCursor(QCursor(Qt::SizeBDiagCursor)); ++ if (pg.y() < parent_->window()->y()) { ++ ypath = parent_->window()->y() - pg.y(); ++ } ++ else { ++ ypath = -(pg.y() - parent_->window()->y()); ++ } ++ if (pg.x() < parent_->window()->geometry().right()) { ++ xpath = -(parent_->window()->geometry().right() - pg.x()); ++ } ++ else { ++ xpath = pg.x() - parent_->window()->geometry().right(); ++ } ++ if ((parent_->window()->height() + ypath) < parent_->window()->minimumHeight()) { ++ ypath = -(parent_->window()->height() - parent_->window()->minimumHeight()); ++ } ++ parent_->window()->setGeometry(parent_->window()->x(), ++ parent_->window()->y() - ypath, ++ parent_->window()->width() + xpath, ++ parent_->window()->height() + ypath); ++ ++ } ++ else if(isLeftButton && isDrag &&!isResize) { ++ setCursor(QCursor(Qt::ArrowCursor)); ++ parent_->window()->move( e->globalPos() - movepath ); ++ } ++ e->accept(); ++} ++ ++void PsiWindowHeader::mouseEnterEvent(const int mouse_x, const int mouse_y, const QRect &geom) ++{ ++ if(mouse_y <= geom.top()+7 ++ && qAbs(mouse_x - geom.left()) <= 4) { ++ inLDRect = true; ++ inRDRect = false; ++ inVRect = false; ++ } ++ else if(mouse_y <= geom.top()+7 ++ && qAbs(mouse_x - geom.right()) <= 4) { ++ inRDRect = true; ++ inLDRect = false; ++ inVRect = false; ++ } ++ else if (mouse_x > (geom.left() + 4) ++ && mouse_x < (geom.right() - 4) ++ && qAbs(mouse_y - geom.top()) <= 4) { ++ inVRect = true; ++ inLDRect = false; ++ inRDRect = false; ++ } ++ else { ++ inVRect = false; ++ inLDRect = false; ++ inRDRect = false; ++ } ++} ++ ++void PsiWindowHeader::mouseReleaseEvent(QMouseEvent *e) ++{ ++ if (e->button() == Qt::LeftButton && isDrag) { ++ movepath.setX(0); ++ movepath.setY(0); ++ isDrag = false; ++ isResize = false; ++ setCursor(QCursor(Qt::ArrowCursor)); ++ } ++ int min_x = qMin(ui_.hideButton->geometry().left(), qMin(ui_.maximizeButton->geometry().left(), ui_.closeButton->geometry().left())); ++ int max_x = qMax(ui_.hideButton->geometry().right(), qMax(ui_.maximizeButton->geometry().right(), ui_.closeButton->geometry().right())); ++ if (e->button() == Qt::MidButton) { ++ if (((e->x() > geometry().left() && e->x() < min_x) ++ || (e->x() < geometry().right() && e->x() > max_x )) ++ && e->y() > geometry().top() ++ && e->y() < geometry().bottom()) { ++ hidePressed(); ++ } ++ } ++ e->accept(); ++} +--- git.orig/src/widgets/psiwindowheader.h ++++ git/src/widgets/psiwindowheader.h +@@ -0,0 +1,65 @@ ++/* ++ * psiwindowheader.cpp ++ * Copyright (C) 2010 Khryukin Evgeny, Vitaly Tonkacheyev ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++ ++#ifndef PSIWINDOWHEADER_H ++#define PSIWINDOWHEADER_H ++ ++#include "ui_psiwindowheader.h" ++ ++#include ++#include ++#include ++ ++class PsiWindowHeader : public QWidget ++{ ++ Q_OBJECT ++public: ++ PsiWindowHeader(QWidget* p); ++ ~PsiWindowHeader(); ++ ++private: ++ Ui::PsiWindowHeader ui_; ++ QWidget *parent_; ++ QPoint movepath; ++ bool isDrag; ++ bool isResize; ++ bool inVRect; ++ bool inLDRect; ++ bool inRDRect; ++ bool maximized; ++ QRect oldSize; ++ QSize defaultSize; ++ void mouseEnterEvent(const int mouse_x, const int mouse_y, const QRect &geom); ++ ++private slots: ++ void hidePressed(); ++ void closePressed(); ++ void maximizePressed(); ++ ++protected: ++ void mouseMoveEvent(QMouseEvent *e); ++ void mousePressEvent(QMouseEvent *e); ++ void mouseReleaseEvent(QMouseEvent *e); ++ void mouseDoubleClickEvent(QMouseEvent *e); ++ ++}; ++ ++#endif // PSIWINDOWHEADER_H +--- git.orig/src/widgets/psiwindowheader.ui ++++ git/src/widgets/psiwindowheader.ui +@@ -0,0 +1,120 @@ ++ ++ ++ PsiWindowHeader ++ ++ ++ ++ 0 ++ 0 ++ 130 ++ 31 ++ ++ ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ true ++ ++ ++ PsiWindowHeader ++ ++ ++ ++ 0 ++ ++ ++ 0 ++ ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ QFrame::NoFrame ++ ++ ++ QFrame::Plain ++ ++ ++ 1 ++ ++ ++ ++ 0 ++ ++ ++ 0 ++ ++ ++ ++ ++ 2 ++ ++ ++ ++ ++ Qt::Horizontal ++ ++ ++ ++ 40 ++ 20 ++ ++ ++ ++ ++ ++ ++ ++ ... ++ ++ ++ true ++ ++ ++ ++ ++ ++ ++ ... ++ ++ ++ true ++ ++ ++ ++ ++ ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ... ++ ++ ++ true ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +--- git.orig/src/widgets/widgets.pri ++++ git/src/widgets/widgets.pri +@@ -16,6 +16,7 @@ SOURCES += \ + $$PWD/psitiplabel.cpp \ + $$PWD/psitabwidget.cpp \ + $$PWD/psitabbar.cpp \ ++ $$PWD/psiwindowheader.cpp \ + $$PWD/actionlineedit.cpp \ + $$PWD/typeaheadfind.cpp + +@@ -43,9 +44,12 @@ HEADERS += \ + $$PWD/psitiplabel.h \ + $$PWD/psitabwidget.h \ + $$PWD/psitabbar.h \ ++ $$PWD/psiwindowheader.h \ + $$PWD/actionlineedit.h \ + $$PWD/typeaheadfind.h + ++FORMS += psiwindowheader.ui ++ + # to remove dependency on iconset and stuff + #DEFINES += WIDGET_PLUGIN +