OSDN Git Service

0fc3c12c68b87d44f604a42db7432ddd3e9de128
[kita/kita.git] / kita / src / part / kitanavi.cpp
1 /**************************************************************************
2 *   Copyright (C) 2003 by Hideki Ikemoto , (c)2004 by 421                 *
3 *   ikemo@wakaba.jp                                                       *
4 *                                                                         *
5 *   This program is free software; you can redistribute it and/or modify  *
6 *   it under the terms of the GNU General Public License as published by  *
7 *   the Free Software Foundation; either version 2 of the License, or     *
8 *   (at your option) any later version.                                   *
9 **************************************************************************/
10
11 #include <qlayout.h>
12 #include <qregexp.h>
13 #include <kaction.h>
14 #include <kstdaccel.h>
15 #include <kpopupmenu.h>
16 #include <qmessagebox.h>
17 #include <klocale.h>
18
19 #include "libkita/datmanager.h"
20 #include "libkita/kita_misc.h"
21 #include "libkita/kita-utf8.h"
22 #include "libkita/parsemisc.h"
23 #include "libkita/signalcollection.h"
24
25 #include "kitanavi.h"
26 #include "kitathreadview.h"
27
28 #define MAX_TABLABEL_LEN 8
29
30 /*----------------------------------------*/
31 /* class KitaNavi                         */
32 /*----------------------------------------*/
33
34 KitaNavi* KitaNavi::m_kitanavi = NULL;
35
36 /* Don't call this directly. Call getKitaNavi instead. */
37 KitaNavi::KitaNavi(
38     QWidget* parent,
39     int navimode)
40     : QFrame( parent, "kita_navif" , WType_TopLevel)
41 {
42     /* default size of kita navi */
43     const int kitanavi_wd = 600;
44     const int kitanavi_ht = 400;
45
46     resize(kitanavi_wd,kitanavi_ht);
47
48     /* mode is defined in kitanavi.h */
49     m_navimode = navimode;
50         
51     m_qtw = new KitaNaviTab(m_navimode,this, "kita_navitab", 0 );
52     m_qtw->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
53     QVBoxLayout *vl = new QVBoxLayout(this);
54     vl->addWidget(m_qtw);
55
56     /* emit when this widget is deactivated */
57     connect( this, SIGNAL( windowDeactivated() ),
58              Kita::SignalCollection::getInstance(), SIGNAL( windowDeactivated() ));
59     
60     /* If this widget is active and receives
61        signal isKitaActive, then emit signal kitaIsActive. */
62     connect( Kita::SignalCollection::getInstance(), SIGNAL( isKitaActive() ),
63              this, SLOT( slotIsKitaActive() ) );
64
65     connect( this, SIGNAL( kitaIsActive() ),
66              Kita::SignalCollection::getInstance(), SIGNAL( kitaIsActive() ) );
67     
68     /* set keyboard accelerator */
69     KActionCollection *kac = new KActionCollection(this);
70     if(m_navimode == KITANAVI_NAVI) KStdAction::find( this, SLOT( slotEditFind() ), kac);
71     new KAction(i18n( "Close Current Thread Tab" ),
72                 KStdAccel::close(),this,SLOT( slotCloseCurrentTab() ),kac,"close_tab" );
73 }
74
75
76 KitaNavi::~KitaNavi(){
77     if(m_qtw) delete m_qtw;
78 }
79
80
81
82 /*-------------------------*/
83 /* show thread on the tab  */
84 /*-------------------------*/  /* private */
85 void KitaNavi::addTab(int mode,
86                       const KURL& datURL,
87                       const QString& query,
88                       int startnum,
89                       int endnum){
90
91     if(m_navimode != KITANAVI_NAVI) return;
92
93     if(isMinimized()) showNormal();
94     raise();
95     setActiveWindow();
96
97     const int margin = 5;
98     int count = 0,totalNum = 0;
99     QString headstr = QString::null;
100     QString footstr = QString::null;
101     QString anchor = QString::null;
102     QString cmbstr = QString::null;
103     QString str, urlstr;
104     QStringList queries;
105     QRegExp qrx(" +");
106     bool ext_OR;
107     QString labelstr;
108                           
109     /* set title and label */
110     switch(mode){
111
112     case KITANAVI_SHOWRES:
113         
114         if(startnum == endnum) labelstr = QString().setNum(startnum);
115         else labelstr = QString( "%1-%2" ).arg(startnum).arg(endnum);
116
117         break;
118         
119     case KITANAVI_EXTBYID:
120     case KITANAVI_EXTBYWORD:
121     case KITANAVI_EXTBYNAME:
122         labelstr = query
123             + " :"+ Kita::ParseMisc::utf8ToUnicode(KITAUTF8_EXTRACT);
124         break;
125
126     case KITANAVI_SHOWRESTREE:
127     case KITANAVI_SHOWREVRESTREE:       
128         labelstr = QString().setNum(startnum);
129         break;
130
131     }
132     labelstr += " :"+QString( "[%1] %2" )
133         .arg( Kita::DatManager::thread_boardName( datURL ) )
134         .arg( Kita::DatManager::thread_name( datURL ) );
135
136     /* create KitaThreadView and setup it */
137     KitaThreadView *view = new KitaThreadView(m_qtw);
138     str = Kita::unescape( labelstr.left( MAX_TABLABEL_LEN ) );
139     m_qtw->addTab(view,str);
140     m_qtw->setTabToolTip(view,labelstr);
141
142     connect( Kita::SignalCollection::getInstance(), SIGNAL( signalChangeStatusbar( const QString&) ),
143              this,SLOT( slotChangeCaption( const QString& )));
144
145     view->setup( datURL, VIEWMODE_KITANAVI );
146     totalNum = Kita::DatManager::getMaxResNumber( datURL );
147
148     /*---------------------------------------------*/    
149     /* copy data from DatManager to KitaThreadView */
150
151     switch(mode){
152
153     case KITANAVI_SHOWRES:
154
155         for(int i = QMAX(1,startnum-margin); i <= QMIN(totalNum,endnum+margin); i++){
156             if(i == startnum) view->domAppendBelt("belt1");
157             str = Kita::DatManager::getDat( datURL ,i);
158             view->domAppendData(str,i,i);
159             if(i == endnum) view->domAppendBelt("belt2");
160         }
161         if(startnum == endnum) headstr = QString("No. %1").arg(startnum);
162         else headstr = QString("No. %1 - %2").arg(startnum).arg(endnum);
163         footstr = headstr;
164
165         anchor = QString().setNum(startnum-1);
166         
167         break;
168         
169         /*--------------------------------*/
170         
171     case KITANAVI_EXTBYID:
172
173         for(int i = 1; i<= totalNum; i++){
174             if(Kita::DatManager::checkID( datURL, query, i )){
175                 str = Kita::DatManager::getDat( datURL, i );
176                 view->domAppendData(str,i,i);
177                 count++;
178             }
179         }
180         headstr = QString("ID:%1 : [%2]").arg(query).arg(count);
181         footstr = headstr;
182         anchor = "header";
183         break;
184
185         /*--------------------------------*/
186         
187     case KITANAVI_EXTBYNAME:
188
189         for(int i = 1; i<= totalNum; i++){
190             if( Kita::DatManager::getName( datURL, i ) == query ){
191                 str = Kita::DatManager::getDat( datURL, i );
192                 view->domAppendData( str, i, i );
193                 count++;
194             }
195         }
196         headstr = Kita::ParseMisc::utf8ToUnicode(KITAUTF8_EXTRACT)
197             +QString(": %1 : [%2]").arg( query ).arg( count );
198         footstr = headstr;
199         anchor = "header";
200         break;
201         
202         /*--------------------------------*/
203
204     case KITANAVI_EXTBYWORD:
205
206         if(query.at(0) == '|'){ /* OR */
207             ext_OR = TRUE;
208             str = query.mid(1);
209         }
210         else{ /* AND */
211             ext_OR = FALSE;
212             str = query;
213         }
214         str.replace(Kita::ParseMisc::utf8ToUnicode(KITAUTF8_ZENSPACE)," ");
215         str.replace(qrx," "); /* pack space */
216         queries  = QStringList::split(" ", str);
217
218         for(int i = 1; i<= totalNum; i++){
219             if(Kita::DatManager::checkWord( datURL, queries, i, ext_OR )){
220                 str = Kita::DatManager::getDat( datURL, i );
221                 view->domAppendData(str,i,i);
222                 count++;
223             }
224         }
225         headstr = Kita::ParseMisc::utf8ToUnicode(KITAUTF8_EXTRACT)
226             +QString(": %1 : [%2]").arg(query).arg(count);
227         footstr = headstr;
228         anchor = "header";
229         cmbstr = "?"+query;
230         break;
231
232         /*--------------------------------*/
233         
234     case KITANAVI_SHOWRESTREE:
235     case KITANAVI_SHOWREVRESTREE:       
236
237         str = QString("[%1] %2 : No.%3 [%4]<br>")
238             .arg( Kita::DatManager::thread_boardName( datURL ) )
239             .arg( Kita::DatManager::thread_name( datURL ) )
240             .arg(startnum ).arg( endnum );
241         urlstr = Kita::DatManager::thread_url( datURL ) + QString().setNum( startnum );
242         str += "<a href=\""+urlstr+"\">"+urlstr+"</a><br>";
243         str += Kita::DatManager::getHtml( datURL, startnum, startnum );
244         if( endnum ){
245         str += "<div style=\"background-color: #CCCCCC; text-align: center\"><br></div>";
246         str += query;
247         }
248         view->domSetInnerHTML(str);
249         
250         break;
251
252     default:
253         break;
254     }
255     
256     m_qtw->showPage(view);
257     view->domApplyChange(labelstr,headstr,footstr,anchor,cmbstr);
258
259     raise();
260     setActiveWindow();
261 }
262
263
264 void KitaNavi::slotChangeCaption( const QString& text )
265 {
266     setCaption("KitaNavi: "+text);
267 }
268
269
270 /* for keyboard acceleration */
271 void KitaNavi::slotCloseCurrentTab()
272 {
273     QWidget* view = m_qtw->currentPage();
274     m_qtw->myRemovePage( view ,TRUE);
275 }
276
277 /* for keyboard acceleration */
278 void KitaNavi::slotEditFind(){
279
280     KitaThreadView* view = static_cast<KitaThreadView*>(m_qtw->currentPage());
281     view->focusSearchCombo();
282 }
283
284 /* when window is deactivated, emit signal to popup */ /* protected */
285 void KitaNavi::windowActivationChange ( bool  )
286 {
287    if(!isActiveWindow()) emit windowDeactivated();
288 }
289
290 /* private slot */
291 void KitaNavi::slotIsKitaActive(){
292     if(isActiveWindow()) emit kitaIsActive();
293 }
294
295
296 /*----------------------------------------------------------------------*/
297 /* interfaces */
298
299 /* static & public */
300
301 /* Don't forget to call this in KitaMainWindow::setupView */ /* static & public */
302 void KitaNavi::createKitaNavi(QWidget* parent, KitaThreadTabWidget* ){
303     if(m_kitanavi == NULL){
304         m_kitanavi = new KitaNavi(parent,KITANAVI_NAVI);
305     }
306 }
307
308 KitaNavi* KitaNavi::getKitaNavi(){
309     if(m_kitanavi) m_kitanavi->show();
310     return m_kitanavi;
311 }
312
313
314 /* show res */
315 void KitaNavi::showKitaNavi( const KURL& datURL, int startnum, int endnum){
316
317     if( ! m_kitanavi ) return;
318     m_kitanavi->show();
319
320     KURL parsedURL = Kita::ParseMisc::parseURLonly( datURL );
321     m_kitanavi->addTab( KITANAVI_SHOWRES, parsedURL, QString::null, startnum, endnum );
322 }
323
324
325
326 /* extract by ID */
327 void KitaNavi::showKitaNaviByID(const KURL& datURL, QString strid){
328
329     if( ! m_kitanavi ) return;
330     m_kitanavi->show();
331
332     KURL parsedURL = Kita::ParseMisc::parseURLonly( datURL );
333     m_kitanavi->addTab( KITANAVI_EXTBYID, parsedURL, strid, 0, 0 );
334 }
335
336
337
338 /* extract by keywords */
339 void KitaNavi::showKitaNaviByWord( const KURL& datURL, QString query){
340
341     if( ! m_kitanavi ) return;
342     m_kitanavi->show();
343
344     KURL parsedURL = Kita::ParseMisc::parseURLonly( datURL );
345     m_kitanavi->addTab( KITANAVI_EXTBYWORD, parsedURL, query, 0, 0 );    
346 }
347
348
349 /* extract by name */
350 void KitaNavi::showKitaNaviByName( const KURL& datURL, QString query){
351
352     if( ! m_kitanavi ) return;
353     m_kitanavi->show();
354
355     KURL parsedURL = Kita::ParseMisc::parseURLonly( datURL );
356     m_kitanavi->addTab( KITANAVI_EXTBYNAME, parsedURL, query, 0, 0 );    
357 }
358
359
360
361 /* res tree */
362 void KitaNavi::showKitaNaviResTree( const KURL& datURL, int resNum){
363
364     if( ! m_kitanavi ) return;
365     m_kitanavi->show();
366
367     int num;
368     KURL parsedURL = Kita::ParseMisc::parseURLonly( datURL );
369     QString htmlstr = Kita::DatManager::getTreeByRes( parsedURL, resNum, num);
370     m_kitanavi->addTab( KITANAVI_SHOWRESTREE, parsedURL, htmlstr, resNum, num);
371 }
372
373
374 /* reverse res tree */
375 void KitaNavi::showKitaNaviRevResTree( const KURL& datURL, int resNum){
376
377     if( ! m_kitanavi ) return;
378     m_kitanavi->show();
379
380     int num;
381     KURL parsedURL = Kita::ParseMisc::parseURLonly( datURL );
382     QString htmlstr = Kita::DatManager::getTreeByResReverse( parsedURL, resNum, num );
383     m_kitanavi->addTab( KITANAVI_SHOWREVRESTREE, parsedURL, htmlstr, resNum, num );
384 }
385
386
387 /*----------------------------------------------------------------------*/
388
389
390 /*----------------------------------------*/
391 /* class KitaNaviTabBar                   */
392 /*----------------------------------------*/
393
394 /* tabbar for kitanavi */
395
396 /* tab menu */
397 void KitaNaviTabBar::contextMenuEvent( QContextMenuEvent* e )
398 {
399     KitaNaviTab* tw = static_cast<KitaNaviTab*>(parentWidget());
400     QWidget* view = tw->currentPage();
401     QWidget* curview = view;
402     QString str;
403     int max = tw->count();
404     int curnum = tw->currentPageIndex();
405
406     KPopupMenu popup( 0 );
407     popup.insertItem(  i18n( "Close this tab" ) , 1 );
408     popup.insertSeparator();
409
410     popup.insertItem( i18n( "Close other tabs" ),  3 );
411     popup.insertItem( i18n( "Close right tabs" ),  4 );            
412     popup.insertItem( i18n( "Close left tabs" ),  5 );
413     popup.insertItem( i18n( "Close all tabs" ),  2 );
414     
415     switch ( popup.exec( e->globalPos() ) ) {
416
417     case 1: /* close */
418         if(view != NULL) tw->myRemovePage( view ,TRUE);
419         break;
420
421     case 2: /* all */
422         while(tw->count() > 0 && view != NULL) view = tw->myRemovePage( view ,TRUE);
423         break;
424
425     case 3: /* other */
426         for(int i=0,i2 = 0;i < max;i++){
427             view = tw->page(i2);
428             if(view != NULL){
429                 if(view != curview) tw->myRemovePage( view ,TRUE);
430                 else i2++;
431             }
432         }
433         break;
434
435     case 4: /* right */
436         for(int i=curnum+1 ; i<max;i++){
437             view = tw->page(curnum+1);
438             if(view != NULL) tw->myRemovePage( view ,TRUE);
439         }
440         break;
441
442     case 5: /* left */
443         for(int i=0 ;i<curnum ;i++){
444             view = tw->page(0);
445             if(view != NULL) tw->myRemovePage( view ,TRUE);
446         }
447         break;
448         
449     default:
450         break;
451     }
452 }
453
454 /*---------------------------------------------------------------------------*/
455
456 /*-------------------------------------*/
457 /* class KitaNaviTab                   */
458 /*-------------------------------------*/
459
460 /* tab widget for kita navi */
461
462 KitaNaviTab::KitaNaviTab(int mode,  QWidget* parent, const char* name, WFlags f)
463         : QTabWidget( parent, name, f )
464 {
465     setTabBar( new KitaNaviTabBar(mode, this ) );
466
467     connect( this, SIGNAL( currentChanged ( QWidget * ) ),
468              SLOT( slotCurrentChanged ( QWidget * ) ) );
469     
470     m_navimode = mode;
471     m_prevview = NULL;
472 }
473
474
475 KitaNaviTab::~KitaNaviTab(){
476
477     if(m_prevview){
478         delete m_prevview;
479         m_prevview = NULL;
480     }
481
482     QWidget* view = currentPage();
483     while(count() > 0 && view != NULL) view = myRemovePage( view ,TRUE);
484 }
485
486
487 void KitaNaviTab::slotCurrentChanged( QWidget * w){
488     static_cast<KitaThreadView *>( w ) ->showStatusBar( "" );
489 }
490
491
492 /*----------------------------------------*/
493 /* remove page                            */
494 /* remove w, then return new current page */
495 /*----------------------------------------*/
496 QWidget* KitaNaviTab::myRemovePage(QWidget* w, bool delCurView){
497
498     QWidget* retw;
499     if(m_prevview){
500         delete m_prevview;
501         m_prevview = NULL;
502     }
503     
504     switch(m_navimode){
505
506     case KITANAVI_NAVI:
507         KitaThreadView* view;    
508         view = static_cast<KitaThreadView*>(w);
509         removePage( view );
510
511         /* Calling this function from KitaThreadView itself will
512            causes the crush. So, backup the instance and delete it later. */
513         if(delCurView) delete view;
514         else m_prevview = view; 
515
516         break;
517     }
518
519     retw = currentPage();
520     if(retw == NULL) parentWidget()->hide();
521
522     return retw;
523 }
524