]> git.lyx.org Git - lyx.git/blob - src/frontends/qt3/QWorkArea.C
* Rename src/frontends/qt2 to src/frontends/qt3,
[lyx.git] / src / frontends / qt3 / QWorkArea.C
1 /**
2  * \file QWorkArea.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "frontends/LyXView.h"
14 #include "BufferView.h"
15
16 #include "QWorkArea.h"
17
18 #include "lcolorcache.h"
19 #include "qt_helpers.h"
20
21 #include "debug.h"
22 #include "funcrequest.h"
23 #include "LColor.h"
24 #include "support/os.h"
25
26 #include <qapplication.h>
27 #include <qclipboard.h>
28 #include <qdragobject.h>
29 #include <qlayout.h>
30 #include <qmainwindow.h>
31 #include <qpainter.h>
32
33 #ifdef Q_WS_X11
34 #include <X11/Xlib.h>
35 #endif
36
37 #ifdef Q_WS_MACX
38 #include <Carbon/Carbon.h>
39 #endif
40
41 #ifdef Q_OS_MAC
42 #include <support/lstrings.h>
43
44 using lyx::support::subst;
45 #endif
46 using std::endl;
47 using std::string;
48
49 namespace os = lyx::support::os;
50
51 namespace {
52 QWorkArea * wa_ptr = 0;
53 }
54
55 QWorkArea::QWorkArea(LyXView & owner, int, int)
56         : WorkArea(), QWidget(qApp->mainWidget()), owner_(owner), painter_(*this)
57 {
58         scrollbar_ = new QScrollBar(QScrollBar::Vertical, this);
59         content_ = new QContentPane(this);
60
61         (static_cast<QMainWindow*>(qApp->mainWidget()))->setCentralWidget(this);
62
63         setFocusProxy(content_);
64         setAcceptDrops(true);
65
66         content_->show();
67
68         // It is said that this helps reduce flicker
69         content_->setBackgroundMode(NoBackground);
70
71         QHBoxLayout * vl = new QHBoxLayout(this);
72         vl->addWidget(content_, 5);
73         vl->addWidget(scrollbar_, 0);
74
75 #ifdef Q_WS_MACX
76         wa_ptr = this;
77 #endif
78         show();
79 }
80
81
82 QWorkArea::~QWorkArea()
83 {
84 }
85
86
87 void QWorkArea::setScrollbarParams(int h, int pos, int line_h)
88 {
89         // do what cursor movement does (some grey)
90         h += height() / 4;
91
92         int max = std::max(0, h - height());
93
94         scrollbar_->setRange(0, max);
95         content_->trackScrollbar(false);
96         scrollbar_->setValue(pos);
97         content_->trackScrollbar(true);
98         scrollbar_->setLineStep(line_h);
99         scrollbar_->setPageStep(height());
100 }
101
102 #ifdef Q_WS_X11
103 bool lyxX11EventFilter(XEvent * xev)
104 {
105         switch (xev->type) {
106         case SelectionRequest:
107                 lyxerr[Debug::GUI] << "X requested selection." << endl;
108                 if (wa_ptr)
109                         wa_ptr->view().view()->selectionRequested();
110                 break;
111         case SelectionClear:
112                 lyxerr[Debug::GUI] << "Lost selection." << endl;
113                 if (wa_ptr)
114                         wa_ptr->view().view()->selectionLost();
115                 break;
116         }
117         return false;
118 }
119 #endif
120
121 #ifdef Q_WS_MACX
122 namespace{
123 OSErr checkAppleEventForMissingParams(const AppleEvent& theAppleEvent)
124  {
125         DescType returnedType;
126         Size actualSize;
127         OSErr err = AEGetAttributePtr(&theAppleEvent, keyMissedKeywordAttr,
128                                       typeWildCard, &returnedType, nil, 0,
129                                       &actualSize);
130         switch (err) {
131         case errAEDescNotFound:
132                 return noErr;
133         case noErr:
134                 return errAEEventNotHandled;
135         default:
136                 return err;
137         }
138  }
139 }
140
141 pascal OSErr handleOpenDocuments(const AppleEvent* inEvent,
142                                  AppleEvent* /*reply*/, long /*refCon*/)
143 {
144         QString s_arg;
145         AEDescList documentList;
146         OSErr err = AEGetParamDesc(inEvent, keyDirectObject, typeAEList,
147                                    &documentList);
148         if (err != noErr)
149                 return err;
150
151         err = checkAppleEventForMissingParams(*inEvent);
152         if (err == noErr) {
153                 long documentCount;
154                 err = AECountItems(&documentList, &documentCount);
155                 for (long documentIndex = 1;
156                      err == noErr && documentIndex <= documentCount;
157                      documentIndex++) {
158                         DescType returnedType;
159                         Size actualSize;
160                         AEKeyword keyword;
161                         FSRef ref;
162                         char qstr_buf[1024];
163                         err = AESizeOfNthItem(&documentList, documentIndex,
164                                               &returnedType, &actualSize);
165                         if (err == noErr) {
166                                 err = AEGetNthPtr(&documentList, documentIndex,
167                                                   typeFSRef, &keyword,
168                                                   &returnedType, (Ptr)&ref,
169                                                   sizeof(FSRef), &actualSize);
170                                 if (err == noErr) {
171                                         FSRefMakePath(&ref, (UInt8*)qstr_buf,
172                                                       1024);
173                                         s_arg=QString::fromUtf8(qstr_buf);
174                                         wa_ptr->view().view()->workAreaDispatch(
175                                                 FuncRequest(LFUN_FILE_OPEN,
176                                                             fromqstr(s_arg)));
177                                         break;
178                                 }
179                         }
180                 } // for ...
181         }
182         AEDisposeDesc(&documentList);
183         return err;
184 }
185 #endif  // Q_WS_MACX
186
187 void QWorkArea::haveSelection(bool own) const
188 {
189         wa_ptr = const_cast<QWorkArea*>(this);
190
191         if (!QApplication::clipboard()->supportsSelection())
192                 return;
193
194         if (own) {
195                 QApplication::clipboard()->setSelectionMode(true);
196                 QApplication::clipboard()->setText(QString());
197         }
198         // We don't need to do anything if own = false, as this case is
199         // handled by QT.
200 }
201
202
203 string const QWorkArea::getClipboard() const
204 {
205         QApplication::clipboard()->setSelectionMode(true);
206         QString str = QApplication::clipboard()->text();
207         if (str.isNull())
208                 return string();
209 #ifdef Q_OS_MAC
210         // The MAC clipboard uses \r for lineendings, and we use \n
211         return subst(fromqstr(str), '\r', '\n');
212 #else
213         return fromqstr(str);
214 #endif
215 }
216
217
218 void QWorkArea::putClipboard(string const & str) const
219 {
220         QApplication::clipboard()->setSelectionMode(true);
221 #ifdef Q_OS_MAC
222         // The MAC clipboard uses \r for lineendings, and we use \n
223         QApplication::clipboard()->setText(toqstr(subst(str, '\n', '\r')));
224 #else
225         QApplication::clipboard()->setText(toqstr(str));
226 #endif
227 }
228
229
230 void QWorkArea::dragEnterEvent(QDragEnterEvent * event)
231 {
232         event->accept(QUriDrag::canDecode(event));
233 }
234
235
236 void QWorkArea::dropEvent(QDropEvent * event)
237 {
238         QStringList files;
239
240         if (QUriDrag::decodeLocalFiles(event, files)) {
241                 lyxerr[Debug::GUI] << "QWorkArea::dropEvent: got URIs!"
242                                    << endl;
243                 for (QStringList::Iterator i = files.begin();
244                      i != files.end(); ++i) {
245                         string const file = os::internal_path(fromqstr(*i));
246                         view().view()->workAreaDispatch(FuncRequest(LFUN_FILE_OPEN, file));
247                 }
248         }
249 }