00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <qcheckbox.h>
00023 #include <qimage.h>
00024 #include <qlabel.h>
00025 #include <qlayout.h>
00026 #include <qtooltip.h>
00027 #include <qlabel.h>
00028 #include <qwhatsthis.h>
00029 #include <qpainter.h>
00030 #include <qtimer.h>
00031
00032 #include <kapplication.h>
00033 #include <kglobalsettings.h>
00034 #include <klocale.h>
00035 #include <kpopupmenu.h>
00036 #include <kiconloader.h>
00037 #include <kdebug.h>
00038
00039 #include "documentPageCache.h"
00040 #include "kvsprefs.h"
00041 #include "marklist.h"
00042
00043
00044 #include "marklist.moc"
00045
00046
00047 namespace {
00048
00050 QPixmap* waitIcon = 0;
00051
00052 }
00053
00054
00055
00056
00057 ThumbnailWidget::ThumbnailWidget(MarkListWidget* _parent, const PageNumber& _pageNumber, DocumentPageCache* _pageCache)
00058 : QWidget(_parent), pageNumber(_pageNumber), pageCache(_pageCache), parent(_parent)
00059 {
00060 setBackgroundMode(Qt::NoBackground);
00061
00062 needsUpdating = true;
00063
00064 if (!waitIcon)
00065 {
00066 waitIcon = new QPixmap(KGlobal::iconLoader()->loadIcon("gear", KIcon::NoGroup, KIcon::SizeMedium));
00067 }
00068 }
00069
00070 void ThumbnailWidget::paintEvent(QPaintEvent* e)
00071 {
00072
00073
00074
00075
00076 if (!parent->isVisible())
00077 {
00078
00079 return;
00080 }
00081
00082 QPainter p(this);
00083 p.setClipRect(e->rect());
00084
00085
00086 p.setRasterOp(Qt::CopyROP);
00087 p.setBrush(NoBrush);
00088 p.setPen(Qt::black);
00089 p.drawRect(rect());
00090
00091
00092
00093 QRect thumbRect = rect();
00094 thumbRect.addCoords(1,1,-1,-1);
00095
00096
00097 if (thumbnail.isNull() || needsUpdating)
00098 {
00099 if (KVSPrefs::changeColors() && KVSPrefs::renderMode() == KVSPrefs::EnumRenderMode::Paper)
00100 p.fillRect(thumbRect, KVSPrefs::paperColor());
00101 else
00102 p.fillRect(thumbRect, Qt::white);
00103
00104
00105
00106
00107
00108
00109 p.drawPixmap(10, 10, *waitIcon);
00110
00111 QTimer::singleShot(50, this, SLOT(setThumbnail()));
00112 return;
00113 }
00114
00115
00116 if (thumbnail.isNull())
00117 {
00118 kdDebug(1223) << "No Thumbnail for page " << pageNumber << " created." << endl;
00119 return;
00120 }
00121
00122
00123
00124
00125 QRect pixmapRect = thumbRect;
00126 pixmapRect.moveBy(-1,-1);
00127
00128
00129 bitBlt (this, thumbRect.topLeft(), &thumbnail, pixmapRect, CopyROP);
00130 }
00131
00132 void ThumbnailWidget::resizeEvent(QResizeEvent*)
00133 {
00134 thumbnail.resize(width(), height());
00135
00136 needsUpdating = true;
00137 }
00138
00139 void ThumbnailWidget::setThumbnail()
00140 {
00141 if (!parent->isVisible())
00142 {
00143
00144
00145
00146
00147 kapp->processEvents();
00148 return;
00149 }
00150
00151 needsUpdating = false;
00152
00153
00154 thumbnail = pageCache->createThumbnail(pageNumber, width() - 2);
00155
00156 if (thumbnail.height() != height() + 2)
00157 setFixedHeight(thumbnail.height() + 2);
00158
00159 update();
00160 kapp->processEvents();
00161 }
00162
00163
00164
00165
00166
00167 MarkListWidget::MarkListWidget(QWidget* _parent, MarkList* _markList, const PageNumber& _pageNumber,
00168 DocumentPageCache* _pageCache, bool _showThumbnail)
00169 : QWidget(_parent), showThumbnail(_showThumbnail), pageNumber(_pageNumber),
00170 pageCache(_pageCache), markList(_markList)
00171 {
00172 QBoxLayout* layout = new QVBoxLayout(this, margin);
00173
00174 thumbnailWidget = 0;
00175 if (showThumbnail)
00176 {
00177 thumbnailWidget = new ThumbnailWidget(this, pageNumber, pageCache);
00178 layout->addWidget(thumbnailWidget, 1, Qt::AlignTop);
00179 }
00180
00181 QBoxLayout* bottomLayout = new QHBoxLayout(layout);
00182
00183 checkBox = new QCheckBox(QString::null, this );
00184 checkBox->setFocusPolicy(QWidget::NoFocus);
00185 QToolTip::add(checkBox, i18n("Select for printing"));
00186 bottomLayout->addWidget(checkBox, 0, Qt::AlignAuto);
00187
00188 pageLabel = new QLabel(QString("%1").arg(pageNumber), this);
00189 bottomLayout->addWidget(pageLabel, 1);
00190
00191 _backgroundColor = KGlobalSettings::baseColor();
00192
00193
00194 if ((pageNumber % 2 == 0) && KGlobalSettings::alternateBackgroundColor().isValid())
00195 _backgroundColor = KGlobalSettings::alternateBackgroundColor();
00196
00197 setPaletteBackgroundColor( _backgroundColor );
00198
00199 show();
00200 }
00201
00202 bool MarkListWidget::isChecked() const
00203 {
00204 return checkBox->isChecked();
00205 }
00206
00207 void MarkListWidget::toggle()
00208 {
00209 checkBox->toggle();
00210 }
00211
00212 void MarkListWidget::setChecked( bool checked )
00213 {
00214 checkBox->setChecked(checked);
00215 }
00216
00217 void MarkListWidget::setSelected( bool selected )
00218 {
00219 if (selected)
00220 setPaletteBackgroundColor( QApplication::palette().active().highlight() );
00221 else
00222 setPaletteBackgroundColor( _backgroundColor );
00223 }
00224
00225 int MarkListWidget::setNewWidth(int width)
00226 {
00227 int height = QMAX(checkBox->height(), pageLabel->height()) + 2*margin;
00228 if (showThumbnail)
00229 {
00230
00231 int thumbnailWidth = QMIN(width, KVSPrefs::maxThumbnailWidth());
00232 int thumbnailHeight = (int)((thumbnailWidth - 2*margin - 2) / pageCache->sizeOfPage(pageNumber).aspectRatio() + 0.5) + 2;
00233
00234
00235 if (thumbnailWidget->size() != QSize(thumbnailWidth, thumbnailHeight))
00236 thumbnailWidget->setFixedSize(thumbnailWidth - 2*margin, thumbnailHeight);
00237
00238 height += thumbnailHeight + 2*margin;
00239 }
00240
00241 setFixedSize(width, height);
00242 return height;
00243 }
00244
00245 bool MarkListWidget::isVisible()
00246 {
00247 QRect visibleRect(markList->contentsX(), markList->contentsY(),
00248 markList->visibleWidth(), markList->visibleHeight());
00249 QRect widgetRect(markList->childX(this), markList->childY(this), width(), height());
00250
00251 if (widgetRect.intersects(visibleRect))
00252 return true;
00253
00254 return false;
00255 }
00256
00257
00258 void MarkListWidget::mousePressEvent(QMouseEvent* e)
00259 {
00260
00261 if (e->button() == LeftButton)
00262 {
00263 emit selected(pageNumber);
00264 }
00265 else if (e->button() == RightButton)
00266 {
00267 emit showPopupMenu(pageNumber, e->globalPos());
00268 }
00269 }
00270
00271
00272
00273
00274
00275 MarkList::MarkList(QWidget* parent, const char* name)
00276 : QScrollView(parent, name), clickedThumbnail(0), showThumbnails(true), contextMenu(0)
00277 {
00278 currentPage = PageNumber::invalidPage;
00279 widgetList.setAutoDelete(true);
00280 setFocusPolicy( QWidget::StrongFocus );
00281
00282 setResizePolicy(QScrollView::Manual);
00283
00284 setVScrollBarMode(QScrollView::AlwaysOn);
00285 setHScrollBarMode(QScrollView::AlwaysOff);
00286
00287 setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
00288
00289 viewport()->setBackgroundMode(Qt::PaletteBase);
00290 enableClipper(true);
00291 }
00292
00293 MarkList::~MarkList()
00294 {
00295 delete contextMenu;
00296 }
00297
00298 void MarkList::setPageCache(DocumentPageCache* _pageCache)
00299 {
00300 pageCache = _pageCache;
00301 }
00302
00303 QValueList<int> MarkList::selectedPages() const
00304 {
00305 QValueList<int> list;
00306 MarkListWidget* item;
00307 for(unsigned int i = 0; i < widgetList.count(); i++)
00308 {
00309 item = widgetList[i];
00310 if (item->isChecked())
00311 list << (i + 1);
00312 }
00313 return list;
00314 }
00315
00316 void MarkList::setNumberOfPages(int numberOfPages, bool _showThumbnails)
00317 {
00318 showThumbnails = _showThumbnails;
00319
00320 widgetList.resize(numberOfPages);
00321
00322 int y = 0;
00323
00324 for (int page = 1; page <= numberOfPages; page++)
00325 {
00326 MarkListWidget* item = new MarkListWidget(viewport(), this, page, pageCache, showThumbnails);
00327
00328 connect(item, SIGNAL(selected(const PageNumber&)), this, SLOT(thumbnailSelected(const PageNumber&)));
00329 connect(item, SIGNAL(showPopupMenu(const PageNumber&, const QPoint&)), this, SLOT(showPopupMenu(const PageNumber&, const QPoint&)));
00330
00331 widgetList.insert(page - 1, item);
00332
00333 int height = item->setNewWidth(visibleWidth());
00334 addChild(item, 0, y);
00335
00336 y += height;
00337 }
00338 resizeContents(visibleWidth(), y);
00339 viewport()->update();
00340 }
00341
00342 void MarkList::thumbnailSelected(const PageNumber& pageNumber)
00343 {
00344
00345
00346 clickedThumbnail = pageNumber;
00347 emit selected(pageNumber);
00348 }
00349
00350 void MarkList::setCurrentPageNumber(const PageNumber& pageNumber)
00351 {
00352 if (!pageNumber.isValid() || pageNumber > (int)widgetList.count())
00353 {
00354 clickedThumbnail = 0;
00355 return;
00356 }
00357
00358 if (currentPage == pageNumber)
00359 return;
00360
00361 MarkListWidget* item;
00362
00363
00364 if (currentPage.isValid() && currentPage <= (int)widgetList.count())
00365 {
00366 item = widgetList[currentPage - 1];
00367 item->setSelected(false);
00368 }
00369
00370
00371 item = widgetList[pageNumber - 1];
00372 item->setSelected(true);
00373
00374
00375
00376
00377 if (clickedThumbnail != pageNumber)
00378 ensureVisible(childX(item), childY(item), 0, item->height());
00379
00380 clickedThumbnail = 0;
00381
00382 currentPage = pageNumber;
00383 }
00384
00385 void MarkList::clear()
00386 {
00387 currentPage = PageNumber::invalidPage;
00388 widgetList.resize(0);
00389 }
00390
00391 void MarkList::selectAll()
00392 {
00393 MarkListWidget* item;
00394 for (unsigned int i = 0; i < widgetList.count(); i++)
00395 {
00396 item = widgetList[i];
00397 item->setChecked(true);
00398 }
00399 }
00400
00401 void MarkList::selectEven()
00402 {
00403 MarkListWidget* item;
00404 for (unsigned int i = 1; i < widgetList.count(); i = i + 2)
00405 {
00406 item = widgetList[i];
00407 item->setChecked(true);
00408 }
00409 }
00410
00411 void MarkList::selectOdd()
00412 {
00413 MarkListWidget* item;
00414 for (unsigned int i = 0; i < widgetList.count(); i = i + 2)
00415 {
00416 item = widgetList[i];
00417 item->setChecked(true);
00418 }
00419 }
00420
00421 void MarkList::toggleSelection()
00422 {
00423 MarkListWidget* item;
00424 for (unsigned int i = 0; i < widgetList.count(); i++)
00425 {
00426 item = widgetList[i];
00427 item->toggle();
00428 }
00429 }
00430
00431 void MarkList::removeSelection()
00432 {
00433 MarkListWidget* item;
00434 for (unsigned int i = 0; i < widgetList.count(); i++)
00435 {
00436 item = widgetList[i];
00437 item->setChecked(false);
00438 }
00439 }
00440
00441 void MarkList::viewportResizeEvent(QResizeEvent*)
00442 {
00443 MarkListWidget* item;
00444
00445 int yold = contentsHeight();
00446 int y = 0;
00447
00448 for (unsigned int i = 0; i < widgetList.count(); i++)
00449 {
00450 item = widgetList[i];
00451 int height = item->setNewWidth(visibleWidth());
00452 moveChild(item, 0, y);
00453
00454 y += height;
00455 }
00456 resizeContents(visibleWidth(), y);
00457
00458
00459 if (yold != contentsHeight())
00460 {
00461
00462 if (currentPage.isValid() && currentPage <= (int)widgetList.count())
00463 {
00464 item = widgetList[currentPage-1];
00465 ensureVisible(childX(item), childY(item), 0, item->height());
00466 }
00467 }
00468
00469 viewport()->update();
00470 }
00471
00472
00473 void MarkList::updateWidgetSize(const PageNumber& pageNumber)
00474 {
00475
00476 if (!pageNumber.isValid() || pageNumber > widgetList.count())
00477 {
00478 kdError() << "MarkList::updateWidgetSize called with invalid pageNumber " << pageNumber << endl;
00479 return;
00480 }
00481
00482 MarkListWidget* item;
00483
00484
00485 item = widgetList[pageNumber - 1];
00486 int height = item->setNewWidth(visibleWidth());
00487 int y = childY(item) + height;
00488
00489
00490 for (unsigned int i = pageNumber; i < widgetList.count(); i++)
00491 {
00492 item = widgetList[i];
00493 int height = item->height();
00494 moveChild(item, 0, y);
00495
00496 y += height;
00497 }
00498 resizeContents(contentsWidth(), y);
00499
00500 viewport()->update();
00501 }
00502
00503 void MarkList::mousePressEvent(QMouseEvent* e)
00504 {
00505 if (e->button() == RightButton)
00506 {
00507
00508
00509 showPopupMenu(PageNumber::invalidPage, e->globalPos());
00510 }
00511 }
00512
00513 void MarkList::slotShowThumbnails(bool show)
00514 {
00515 if (show != showThumbnails)
00516 {
00517 int numOfPages = widgetList.count();
00518
00519 if (numOfPages == 0)
00520 return;
00521
00522
00523 PageNumber _currentPage = currentPage;
00524
00525
00526 QValueVector<bool> selections;
00527 selections.resize(widgetList.count());
00528 for (unsigned int i = 0; i < widgetList.count(); i++)
00529 selections[i] = widgetList[i]->isChecked();
00530
00531
00532 clear();
00533 setNumberOfPages(numOfPages, show);
00534
00535
00536 setCurrentPageNumber(_currentPage);
00537
00538
00539 for (unsigned int i = 0; i < widgetList.count(); i++)
00540 widgetList[i]->setChecked(selections[i]);
00541 }
00542 }
00543
00544
00545 void MarkList::repaintThumbnails()
00546 {
00547 bool show = showThumbnails;
00548 int numOfPages = widgetList.count();
00549
00550
00551 clear();
00552 setNumberOfPages(numOfPages, show);
00553 }
00554
00555
00556 void MarkList::showPopupMenu(const PageNumber& pageNumber, const QPoint& position)
00557 {
00558 if (contextMenu == 0)
00559 {
00560
00561 contextMenu = new KPopupMenu(this, "markListContext");
00562
00563 contextMenu->insertItem(i18n("Select &Current Page"), 0);
00564 contextMenu->insertItem(i18n("Select &All Pages"), 1);
00565 contextMenu->insertItem(i18n("Select &Even Pages"), 2);
00566 contextMenu->insertItem(i18n("Select &Odd Pages"), 3);
00567 contextMenu->insertItem(i18n("&Invert Selection"), 4);
00568 contextMenu->insertItem(i18n("&Deselect All Pages"), 5);
00569 }
00570
00571 if (widgetList.count() == 0)
00572 {
00573 for (int i = 0; i <= 5; i++)
00574 contextMenu->setItemEnabled(i, false);
00575 }
00576 else
00577 {
00578 for (int i = 0; i <= 5; i++)
00579 contextMenu->setItemEnabled(i, true);
00580 }
00581
00582
00583 if (pageNumber.isValid() && pageNumber <= (int)widgetList.count())
00584 contextMenu->setItemEnabled(0, true);
00585 else
00586 contextMenu->setItemEnabled(0, false);
00587
00588
00589 switch(contextMenu->exec(position))
00590 {
00591 case 0:
00592 widgetList[pageNumber - 1]->toggle();
00593 break;
00594
00595 case 1:
00596 selectAll();
00597 break;
00598
00599 case 2:
00600 selectEven();
00601 break;
00602
00603 case 3:
00604 selectOdd();
00605 break;
00606
00607 case 4:
00608 toggleSelection();
00609 break;
00610
00611 case 5:
00612 removeSelection();
00613 break;
00614 }
00615 }
00616